##// END OF EJS Templates
Fixed: Simultaneous wiki updates cause internal error (#7939)....
Jean-Philippe Lang -
r5065:3d551f97e14e
parent child
Show More
@@ -1,276 +1,274
1 # Redmine - project management software
1 # Redmine - project management software
2 # Copyright (C) 2006-2011 Jean-Philippe Lang
2 # Copyright (C) 2006-2011 Jean-Philippe Lang
3 #
3 #
4 # This program is free software; you can redistribute it and/or
4 # This program is free software; you can redistribute it and/or
5 # modify it under the terms of the GNU General Public License
5 # modify it under the terms of the GNU General Public License
6 # as published by the Free Software Foundation; either version 2
6 # as published by the Free Software Foundation; either version 2
7 # of the License, or (at your option) any later version.
7 # of the License, or (at your option) any later version.
8 #
8 #
9 # This program is distributed in the hope that it will be useful,
9 # This program is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 # GNU General Public License for more details.
12 # GNU General Public License for more details.
13 #
13 #
14 # You should have received a copy of the GNU General Public License
14 # You should have received a copy of the GNU General Public License
15 # along with this program; if not, write to the Free Software
15 # along with this program; if not, write to the Free Software
16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17
17
18 require 'diff'
18 require 'diff'
19
19
20 # The WikiController follows the Rails REST controller pattern but with
20 # The WikiController follows the Rails REST controller pattern but with
21 # a few differences
21 # a few differences
22 #
22 #
23 # * index - shows a list of WikiPages grouped by page or date
23 # * index - shows a list of WikiPages grouped by page or date
24 # * new - not used
24 # * new - not used
25 # * create - not used
25 # * create - not used
26 # * show - will also show the form for creating a new wiki page
26 # * show - will also show the form for creating a new wiki page
27 # * edit - used to edit an existing or new page
27 # * edit - used to edit an existing or new page
28 # * update - used to save a wiki page update to the database, including new pages
28 # * update - used to save a wiki page update to the database, including new pages
29 # * destroy - normal
29 # * destroy - normal
30 #
30 #
31 # Other member and collection methods are also used
31 # Other member and collection methods are also used
32 #
32 #
33 # TODO: still being worked on
33 # TODO: still being worked on
34 class WikiController < ApplicationController
34 class WikiController < ApplicationController
35 default_search_scope :wiki_pages
35 default_search_scope :wiki_pages
36 before_filter :find_wiki, :authorize
36 before_filter :find_wiki, :authorize
37 before_filter :find_existing_page, :only => [:rename, :protect, :history, :diff, :annotate, :add_attachment, :destroy]
37 before_filter :find_existing_page, :only => [:rename, :protect, :history, :diff, :annotate, :add_attachment, :destroy]
38
38
39 verify :method => :post, :only => [:protect], :redirect_to => { :action => :show }
39 verify :method => :post, :only => [:protect], :redirect_to => { :action => :show }
40
40
41 helper :attachments
41 helper :attachments
42 include AttachmentsHelper
42 include AttachmentsHelper
43 helper :watchers
43 helper :watchers
44
44
45 # List of pages, sorted alphabetically and by parent (hierarchy)
45 # List of pages, sorted alphabetically and by parent (hierarchy)
46 def index
46 def index
47 load_pages_for_index
47 load_pages_for_index
48 @pages_by_parent_id = @pages.group_by(&:parent_id)
48 @pages_by_parent_id = @pages.group_by(&:parent_id)
49 end
49 end
50
50
51 # List of page, by last update
51 # List of page, by last update
52 def date_index
52 def date_index
53 load_pages_for_index
53 load_pages_for_index
54 @pages_by_date = @pages.group_by {|p| p.updated_on.to_date}
54 @pages_by_date = @pages.group_by {|p| p.updated_on.to_date}
55 end
55 end
56
56
57 # display a page (in editing mode if it doesn't exist)
57 # display a page (in editing mode if it doesn't exist)
58 def show
58 def show
59 page_title = params[:id]
59 page_title = params[:id]
60 @page = @wiki.find_or_new_page(page_title)
60 @page = @wiki.find_or_new_page(page_title)
61 if @page.new_record?
61 if @page.new_record?
62 if User.current.allowed_to?(:edit_wiki_pages, @project) && editable?
62 if User.current.allowed_to?(:edit_wiki_pages, @project) && editable?
63 edit
63 edit
64 render :action => 'edit'
64 render :action => 'edit'
65 else
65 else
66 render_404
66 render_404
67 end
67 end
68 return
68 return
69 end
69 end
70 if params[:version] && !User.current.allowed_to?(:view_wiki_edits, @project)
70 if params[:version] && !User.current.allowed_to?(:view_wiki_edits, @project)
71 # Redirects user to the current version if he's not allowed to view previous versions
71 # Redirects user to the current version if he's not allowed to view previous versions
72 redirect_to :version => nil
72 redirect_to :version => nil
73 return
73 return
74 end
74 end
75 @content = @page.content_for_version(params[:version])
75 @content = @page.content_for_version(params[:version])
76 if User.current.allowed_to?(:export_wiki_pages, @project)
76 if User.current.allowed_to?(:export_wiki_pages, @project)
77 if params[:format] == 'html'
77 if params[:format] == 'html'
78 export = render_to_string :action => 'export', :layout => false
78 export = render_to_string :action => 'export', :layout => false
79 send_data(export, :type => 'text/html', :filename => "#{@page.title}.html")
79 send_data(export, :type => 'text/html', :filename => "#{@page.title}.html")
80 return
80 return
81 elsif params[:format] == 'txt'
81 elsif params[:format] == 'txt'
82 send_data(@content.text, :type => 'text/plain', :filename => "#{@page.title}.txt")
82 send_data(@content.text, :type => 'text/plain', :filename => "#{@page.title}.txt")
83 return
83 return
84 end
84 end
85 end
85 end
86 @editable = editable?
86 @editable = editable?
87 render :action => 'show'
87 render :action => 'show'
88 end
88 end
89
89
90 # edit an existing page or a new one
90 # edit an existing page or a new one
91 def edit
91 def edit
92 @page = @wiki.find_or_new_page(params[:id])
92 @page = @wiki.find_or_new_page(params[:id])
93 return render_403 unless editable?
93 return render_403 unless editable?
94 @page.content = WikiContent.new(:page => @page) if @page.new_record?
94 @page.content = WikiContent.new(:page => @page) if @page.new_record?
95
95
96 @content = @page.content_for_version(params[:version])
96 @content = @page.content_for_version(params[:version])
97 @content.text = initial_page_content(@page) if @content.text.blank?
97 @content.text = initial_page_content(@page) if @content.text.blank?
98 # don't keep previous comment
98 # don't keep previous comment
99 @content.comments = nil
99 @content.comments = nil
100
100
101 # To prevent StaleObjectError exception when reverting to a previous version
101 # To prevent StaleObjectError exception when reverting to a previous version
102 @content.version = @page.content.version
102 @content.version = @page.content.version
103 rescue ActiveRecord::StaleObjectError
104 # Optimistic locking exception
105 flash[:error] = l(:notice_locking_conflict)
106 end
103 end
107
104
108 verify :method => :put, :only => :update, :render => {:nothing => true, :status => :method_not_allowed }
105 verify :method => :put, :only => :update, :render => {:nothing => true, :status => :method_not_allowed }
109 # Creates a new page or updates an existing one
106 # Creates a new page or updates an existing one
110 def update
107 def update
111 @page = @wiki.find_or_new_page(params[:id])
108 @page = @wiki.find_or_new_page(params[:id])
112 return render_403 unless editable?
109 return render_403 unless editable?
113 @page.content = WikiContent.new(:page => @page) if @page.new_record?
110 @page.content = WikiContent.new(:page => @page) if @page.new_record?
114
111
115 @content = @page.content_for_version(params[:version])
112 @content = @page.content_for_version(params[:version])
116 @content.text = initial_page_content(@page) if @content.text.blank?
113 @content.text = initial_page_content(@page) if @content.text.blank?
117 # don't keep previous comment
114 # don't keep previous comment
118 @content.comments = nil
115 @content.comments = nil
119
116
120 if !@page.new_record? && params[:content].present? && @content.text == params[:content][:text]
117 if !@page.new_record? && params[:content].present? && @content.text == params[:content][:text]
121 attachments = Attachment.attach_files(@page, params[:attachments])
118 attachments = Attachment.attach_files(@page, params[:attachments])
122 render_attachment_warning_if_needed(@page)
119 render_attachment_warning_if_needed(@page)
123 # don't save if text wasn't changed
120 # don't save if text wasn't changed
124 redirect_to :action => 'show', :project_id => @project, :id => @page.title
121 redirect_to :action => 'show', :project_id => @project, :id => @page.title
125 return
122 return
126 end
123 end
127 @content.attributes = params[:content]
124 @content.attributes = params[:content]
128 @content.author = User.current
125 @content.author = User.current
129 # if page is new @page.save will also save content, but not if page isn't a new record
126 # if page is new @page.save will also save content, but not if page isn't a new record
130 if (@page.new_record? ? @page.save : @content.save)
127 if (@page.new_record? ? @page.save : @content.save)
131 attachments = Attachment.attach_files(@page, params[:attachments])
128 attachments = Attachment.attach_files(@page, params[:attachments])
132 render_attachment_warning_if_needed(@page)
129 render_attachment_warning_if_needed(@page)
133 call_hook(:controller_wiki_edit_after_save, { :params => params, :page => @page})
130 call_hook(:controller_wiki_edit_after_save, { :params => params, :page => @page})
134 redirect_to :action => 'show', :project_id => @project, :id => @page.title
131 redirect_to :action => 'show', :project_id => @project, :id => @page.title
135 else
132 else
136 render :action => 'edit'
133 render :action => 'edit'
137 end
134 end
138
135
139 rescue ActiveRecord::StaleObjectError
136 rescue ActiveRecord::StaleObjectError
140 # Optimistic locking exception
137 # Optimistic locking exception
141 flash[:error] = l(:notice_locking_conflict)
138 flash.now[:error] = l(:notice_locking_conflict)
139 render :action => 'edit'
142 end
140 end
143
141
144 # rename a page
142 # rename a page
145 def rename
143 def rename
146 return render_403 unless editable?
144 return render_403 unless editable?
147 @page.redirect_existing_links = true
145 @page.redirect_existing_links = true
148 # used to display the *original* title if some AR validation errors occur
146 # used to display the *original* title if some AR validation errors occur
149 @original_title = @page.pretty_title
147 @original_title = @page.pretty_title
150 if request.post? && @page.update_attributes(params[:wiki_page])
148 if request.post? && @page.update_attributes(params[:wiki_page])
151 flash[:notice] = l(:notice_successful_update)
149 flash[:notice] = l(:notice_successful_update)
152 redirect_to :action => 'show', :project_id => @project, :id => @page.title
150 redirect_to :action => 'show', :project_id => @project, :id => @page.title
153 end
151 end
154 end
152 end
155
153
156 def protect
154 def protect
157 @page.update_attribute :protected, params[:protected]
155 @page.update_attribute :protected, params[:protected]
158 redirect_to :action => 'show', :project_id => @project, :id => @page.title
156 redirect_to :action => 'show', :project_id => @project, :id => @page.title
159 end
157 end
160
158
161 # show page history
159 # show page history
162 def history
160 def history
163 @version_count = @page.content.versions.count
161 @version_count = @page.content.versions.count
164 @version_pages = Paginator.new self, @version_count, per_page_option, params['p']
162 @version_pages = Paginator.new self, @version_count, per_page_option, params['p']
165 # don't load text
163 # don't load text
166 @versions = @page.content.versions.find :all,
164 @versions = @page.content.versions.find :all,
167 :select => "id, author_id, comments, updated_on, version",
165 :select => "id, author_id, comments, updated_on, version",
168 :order => 'version DESC',
166 :order => 'version DESC',
169 :limit => @version_pages.items_per_page + 1,
167 :limit => @version_pages.items_per_page + 1,
170 :offset => @version_pages.current.offset
168 :offset => @version_pages.current.offset
171
169
172 render :layout => false if request.xhr?
170 render :layout => false if request.xhr?
173 end
171 end
174
172
175 def diff
173 def diff
176 @diff = @page.diff(params[:version], params[:version_from])
174 @diff = @page.diff(params[:version], params[:version_from])
177 render_404 unless @diff
175 render_404 unless @diff
178 end
176 end
179
177
180 def annotate
178 def annotate
181 @annotate = @page.annotate(params[:version])
179 @annotate = @page.annotate(params[:version])
182 render_404 unless @annotate
180 render_404 unless @annotate
183 end
181 end
184
182
185 verify :method => :delete, :only => [:destroy], :redirect_to => { :action => :show }
183 verify :method => :delete, :only => [:destroy], :redirect_to => { :action => :show }
186 # Removes a wiki page and its history
184 # Removes a wiki page and its history
187 # Children can be either set as root pages, removed or reassigned to another parent page
185 # Children can be either set as root pages, removed or reassigned to another parent page
188 def destroy
186 def destroy
189 return render_403 unless editable?
187 return render_403 unless editable?
190
188
191 @descendants_count = @page.descendants.size
189 @descendants_count = @page.descendants.size
192 if @descendants_count > 0
190 if @descendants_count > 0
193 case params[:todo]
191 case params[:todo]
194 when 'nullify'
192 when 'nullify'
195 # Nothing to do
193 # Nothing to do
196 when 'destroy'
194 when 'destroy'
197 # Removes all its descendants
195 # Removes all its descendants
198 @page.descendants.each(&:destroy)
196 @page.descendants.each(&:destroy)
199 when 'reassign'
197 when 'reassign'
200 # Reassign children to another parent page
198 # Reassign children to another parent page
201 reassign_to = @wiki.pages.find_by_id(params[:reassign_to_id].to_i)
199 reassign_to = @wiki.pages.find_by_id(params[:reassign_to_id].to_i)
202 return unless reassign_to
200 return unless reassign_to
203 @page.children.each do |child|
201 @page.children.each do |child|
204 child.update_attribute(:parent, reassign_to)
202 child.update_attribute(:parent, reassign_to)
205 end
203 end
206 else
204 else
207 @reassignable_to = @wiki.pages - @page.self_and_descendants
205 @reassignable_to = @wiki.pages - @page.self_and_descendants
208 return
206 return
209 end
207 end
210 end
208 end
211 @page.destroy
209 @page.destroy
212 redirect_to :action => 'index', :project_id => @project
210 redirect_to :action => 'index', :project_id => @project
213 end
211 end
214
212
215 # Export wiki to a single html file
213 # Export wiki to a single html file
216 def export
214 def export
217 if User.current.allowed_to?(:export_wiki_pages, @project)
215 if User.current.allowed_to?(:export_wiki_pages, @project)
218 @pages = @wiki.pages.find :all, :order => 'title'
216 @pages = @wiki.pages.find :all, :order => 'title'
219 export = render_to_string :action => 'export_multiple', :layout => false
217 export = render_to_string :action => 'export_multiple', :layout => false
220 send_data(export, :type => 'text/html', :filename => "wiki.html")
218 send_data(export, :type => 'text/html', :filename => "wiki.html")
221 else
219 else
222 redirect_to :action => 'show', :project_id => @project, :id => nil
220 redirect_to :action => 'show', :project_id => @project, :id => nil
223 end
221 end
224 end
222 end
225
223
226 def preview
224 def preview
227 page = @wiki.find_page(params[:id])
225 page = @wiki.find_page(params[:id])
228 # page is nil when previewing a new page
226 # page is nil when previewing a new page
229 return render_403 unless page.nil? || editable?(page)
227 return render_403 unless page.nil? || editable?(page)
230 if page
228 if page
231 @attachements = page.attachments
229 @attachements = page.attachments
232 @previewed = page.content
230 @previewed = page.content
233 end
231 end
234 @text = params[:content][:text]
232 @text = params[:content][:text]
235 render :partial => 'common/preview'
233 render :partial => 'common/preview'
236 end
234 end
237
235
238 def add_attachment
236 def add_attachment
239 return render_403 unless editable?
237 return render_403 unless editable?
240 attachments = Attachment.attach_files(@page, params[:attachments])
238 attachments = Attachment.attach_files(@page, params[:attachments])
241 render_attachment_warning_if_needed(@page)
239 render_attachment_warning_if_needed(@page)
242 redirect_to :action => 'show', :id => @page.title, :project_id => @project
240 redirect_to :action => 'show', :id => @page.title, :project_id => @project
243 end
241 end
244
242
245 private
243 private
246
244
247 def find_wiki
245 def find_wiki
248 @project = Project.find(params[:project_id])
246 @project = Project.find(params[:project_id])
249 @wiki = @project.wiki
247 @wiki = @project.wiki
250 render_404 unless @wiki
248 render_404 unless @wiki
251 rescue ActiveRecord::RecordNotFound
249 rescue ActiveRecord::RecordNotFound
252 render_404
250 render_404
253 end
251 end
254
252
255 # Finds the requested page and returns a 404 error if it doesn't exist
253 # Finds the requested page and returns a 404 error if it doesn't exist
256 def find_existing_page
254 def find_existing_page
257 @page = @wiki.find_page(params[:id])
255 @page = @wiki.find_page(params[:id])
258 render_404 if @page.nil?
256 render_404 if @page.nil?
259 end
257 end
260
258
261 # Returns true if the current user is allowed to edit the page, otherwise false
259 # Returns true if the current user is allowed to edit the page, otherwise false
262 def editable?(page = @page)
260 def editable?(page = @page)
263 page.editable_by?(User.current)
261 page.editable_by?(User.current)
264 end
262 end
265
263
266 # Returns the default content of a new wiki page
264 # Returns the default content of a new wiki page
267 def initial_page_content(page)
265 def initial_page_content(page)
268 helper = Redmine::WikiFormatting.helper_for(Setting.text_formatting)
266 helper = Redmine::WikiFormatting.helper_for(Setting.text_formatting)
269 extend helper unless self.instance_of?(helper)
267 extend helper unless self.instance_of?(helper)
270 helper.instance_method(:initial_page_content).bind(self).call(page)
268 helper.instance_method(:initial_page_content).bind(self).call(page)
271 end
269 end
272
270
273 def load_pages_for_index
271 def load_pages_for_index
274 @pages = @wiki.pages.with_updated_on.all(:order => 'title', :include => {:wiki => :project})
272 @pages = @wiki.pages.with_updated_on.all(:order => 'title', :include => {:wiki => :project})
275 end
273 end
276 end
274 end
@@ -1,460 +1,496
1 # Redmine - project management software
1 # Redmine - project management software
2 # Copyright (C) 2006-2011 Jean-Philippe Lang
2 # Copyright (C) 2006-2011 Jean-Philippe Lang
3 #
3 #
4 # This program is free software; you can redistribute it and/or
4 # This program is free software; you can redistribute it and/or
5 # modify it under the terms of the GNU General Public License
5 # modify it under the terms of the GNU General Public License
6 # as published by the Free Software Foundation; either version 2
6 # as published by the Free Software Foundation; either version 2
7 # of the License, or (at your option) any later version.
7 # of the License, or (at your option) any later version.
8 #
8 #
9 # This program is distributed in the hope that it will be useful,
9 # This program is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 # GNU General Public License for more details.
12 # GNU General Public License for more details.
13 #
13 #
14 # You should have received a copy of the GNU General Public License
14 # You should have received a copy of the GNU General Public License
15 # along with this program; if not, write to the Free Software
15 # along with this program; if not, write to the Free Software
16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17
17
18 require File.expand_path('../../test_helper', __FILE__)
18 require File.expand_path('../../test_helper', __FILE__)
19 require 'wiki_controller'
19 require 'wiki_controller'
20
20
21 # Re-raise errors caught by the controller.
21 # Re-raise errors caught by the controller.
22 class WikiController; def rescue_action(e) raise e end; end
22 class WikiController; def rescue_action(e) raise e end; end
23
23
24 class WikiControllerTest < ActionController::TestCase
24 class WikiControllerTest < ActionController::TestCase
25 fixtures :projects, :users, :roles, :members, :member_roles, :enabled_modules, :wikis, :wiki_pages, :wiki_contents, :wiki_content_versions, :attachments
25 fixtures :projects, :users, :roles, :members, :member_roles, :enabled_modules, :wikis, :wiki_pages, :wiki_contents, :wiki_content_versions, :attachments
26
26
27 def setup
27 def setup
28 @controller = WikiController.new
28 @controller = WikiController.new
29 @request = ActionController::TestRequest.new
29 @request = ActionController::TestRequest.new
30 @response = ActionController::TestResponse.new
30 @response = ActionController::TestResponse.new
31 User.current = nil
31 User.current = nil
32 end
32 end
33
33
34 def test_show_start_page
34 def test_show_start_page
35 get :show, :project_id => 'ecookbook'
35 get :show, :project_id => 'ecookbook'
36 assert_response :success
36 assert_response :success
37 assert_template 'show'
37 assert_template 'show'
38 assert_tag :tag => 'h1', :content => /CookBook documentation/
38 assert_tag :tag => 'h1', :content => /CookBook documentation/
39
39
40 # child_pages macro
40 # child_pages macro
41 assert_tag :ul, :attributes => { :class => 'pages-hierarchy' },
41 assert_tag :ul, :attributes => { :class => 'pages-hierarchy' },
42 :child => { :tag => 'li',
42 :child => { :tag => 'li',
43 :child => { :tag => 'a', :attributes => { :href => '/projects/ecookbook/wiki/Page_with_an_inline_image' },
43 :child => { :tag => 'a', :attributes => { :href => '/projects/ecookbook/wiki/Page_with_an_inline_image' },
44 :content => 'Page with an inline image' } }
44 :content => 'Page with an inline image' } }
45 end
45 end
46
46
47 def test_show_page_with_name
47 def test_show_page_with_name
48 get :show, :project_id => 1, :id => 'Another_page'
48 get :show, :project_id => 1, :id => 'Another_page'
49 assert_response :success
49 assert_response :success
50 assert_template 'show'
50 assert_template 'show'
51 assert_tag :tag => 'h1', :content => /Another page/
51 assert_tag :tag => 'h1', :content => /Another page/
52 # Included page with an inline image
52 # Included page with an inline image
53 assert_tag :tag => 'p', :content => /This is an inline image/
53 assert_tag :tag => 'p', :content => /This is an inline image/
54 assert_tag :tag => 'img', :attributes => { :src => '/attachments/download/3',
54 assert_tag :tag => 'img', :attributes => { :src => '/attachments/download/3',
55 :alt => 'This is a logo' }
55 :alt => 'This is a logo' }
56 end
56 end
57
57
58 def test_show_with_sidebar
58 def test_show_with_sidebar
59 page = Project.find(1).wiki.pages.new(:title => 'Sidebar')
59 page = Project.find(1).wiki.pages.new(:title => 'Sidebar')
60 page.content = WikiContent.new(:text => 'Side bar content for test_show_with_sidebar')
60 page.content = WikiContent.new(:text => 'Side bar content for test_show_with_sidebar')
61 page.save!
61 page.save!
62
62
63 get :show, :project_id => 1, :id => 'Another_page'
63 get :show, :project_id => 1, :id => 'Another_page'
64 assert_response :success
64 assert_response :success
65 assert_tag :tag => 'div', :attributes => {:id => 'sidebar'},
65 assert_tag :tag => 'div', :attributes => {:id => 'sidebar'},
66 :content => /Side bar content for test_show_with_sidebar/
66 :content => /Side bar content for test_show_with_sidebar/
67 end
67 end
68
68
69 def test_show_unexistent_page_without_edit_right
69 def test_show_unexistent_page_without_edit_right
70 get :show, :project_id => 1, :id => 'Unexistent page'
70 get :show, :project_id => 1, :id => 'Unexistent page'
71 assert_response 404
71 assert_response 404
72 end
72 end
73
73
74 def test_show_unexistent_page_with_edit_right
74 def test_show_unexistent_page_with_edit_right
75 @request.session[:user_id] = 2
75 @request.session[:user_id] = 2
76 get :show, :project_id => 1, :id => 'Unexistent page'
76 get :show, :project_id => 1, :id => 'Unexistent page'
77 assert_response :success
77 assert_response :success
78 assert_template 'edit'
78 assert_template 'edit'
79 end
79 end
80
80
81 def test_create_page
81 def test_create_page
82 @request.session[:user_id] = 2
82 @request.session[:user_id] = 2
83 put :update, :project_id => 1,
83 put :update, :project_id => 1,
84 :id => 'New page',
84 :id => 'New page',
85 :content => {:comments => 'Created the page',
85 :content => {:comments => 'Created the page',
86 :text => "h1. New page\n\nThis is a new page",
86 :text => "h1. New page\n\nThis is a new page",
87 :version => 0}
87 :version => 0}
88 assert_redirected_to :action => 'show', :project_id => 'ecookbook', :id => 'New_page'
88 assert_redirected_to :action => 'show', :project_id => 'ecookbook', :id => 'New_page'
89 page = Project.find(1).wiki.find_page('New page')
89 page = Project.find(1).wiki.find_page('New page')
90 assert !page.new_record?
90 assert !page.new_record?
91 assert_not_nil page.content
91 assert_not_nil page.content
92 assert_equal 'Created the page', page.content.comments
92 assert_equal 'Created the page', page.content.comments
93 end
93 end
94
94
95 def test_create_page_with_attachments
95 def test_create_page_with_attachments
96 @request.session[:user_id] = 2
96 @request.session[:user_id] = 2
97 assert_difference 'WikiPage.count' do
97 assert_difference 'WikiPage.count' do
98 assert_difference 'Attachment.count' do
98 assert_difference 'Attachment.count' do
99 put :update, :project_id => 1,
99 put :update, :project_id => 1,
100 :id => 'New page',
100 :id => 'New page',
101 :content => {:comments => 'Created the page',
101 :content => {:comments => 'Created the page',
102 :text => "h1. New page\n\nThis is a new page",
102 :text => "h1. New page\n\nThis is a new page",
103 :version => 0},
103 :version => 0},
104 :attachments => {'1' => {'file' => uploaded_test_file('testfile.txt', 'text/plain')}}
104 :attachments => {'1' => {'file' => uploaded_test_file('testfile.txt', 'text/plain')}}
105 end
105 end
106 end
106 end
107 page = Project.find(1).wiki.find_page('New page')
107 page = Project.find(1).wiki.find_page('New page')
108 assert_equal 1, page.attachments.count
108 assert_equal 1, page.attachments.count
109 assert_equal 'testfile.txt', page.attachments.first.filename
109 assert_equal 'testfile.txt', page.attachments.first.filename
110 end
110 end
111
111
112 def test_update_page
112 def test_update_page
113 @request.session[:user_id] = 2
113 @request.session[:user_id] = 2
114 assert_no_difference 'WikiPage.count' do
114 assert_no_difference 'WikiPage.count' do
115 assert_no_difference 'WikiContent.count' do
115 assert_no_difference 'WikiContent.count' do
116 assert_difference 'WikiContent::Version.count' do
116 assert_difference 'WikiContent::Version.count' do
117 put :update, :project_id => 1,
117 put :update, :project_id => 1,
118 :id => 'Another_page',
118 :id => 'Another_page',
119 :content => {
119 :content => {
120 :comments => "my comments",
120 :comments => "my comments",
121 :text => "edited",
121 :text => "edited",
122 :version => 1
122 :version => 1
123 }
123 }
124 end
124 end
125 end
125 end
126 end
126 end
127 assert_redirected_to '/projects/ecookbook/wiki/Another_page'
127 assert_redirected_to '/projects/ecookbook/wiki/Another_page'
128
128
129 page = Wiki.find(1).pages.find_by_title('Another_page')
129 page = Wiki.find(1).pages.find_by_title('Another_page')
130 assert_equal "edited", page.content.text
130 assert_equal "edited", page.content.text
131 assert_equal 2, page.content.version
131 assert_equal 2, page.content.version
132 assert_equal "my comments", page.content.comments
132 assert_equal "my comments", page.content.comments
133 end
133 end
134
134
135 def test_update_page_with_failure
135 def test_update_page_with_failure
136 @request.session[:user_id] = 2
136 @request.session[:user_id] = 2
137 assert_no_difference 'WikiPage.count' do
137 assert_no_difference 'WikiPage.count' do
138 assert_no_difference 'WikiContent.count' do
138 assert_no_difference 'WikiContent.count' do
139 assert_no_difference 'WikiContent::Version.count' do
139 assert_no_difference 'WikiContent::Version.count' do
140 put :update, :project_id => 1,
140 put :update, :project_id => 1,
141 :id => 'Another_page',
141 :id => 'Another_page',
142 :content => {
142 :content => {
143 :comments => 'a' * 300, # failure here, comment is too long
143 :comments => 'a' * 300, # failure here, comment is too long
144 :text => 'edited',
144 :text => 'edited',
145 :version => 1
145 :version => 1
146 }
146 }
147 end
147 end
148 end
148 end
149 end
149 end
150 assert_response :success
150 assert_response :success
151 assert_template 'edit'
151 assert_template 'edit'
152
152
153 assert_error_tag :descendant => {:content => /Comment is too long/}
153 assert_error_tag :descendant => {:content => /Comment is too long/}
154 assert_tag :tag => 'textarea', :attributes => {:id => 'content_text'}, :content => 'edited'
154 assert_tag :tag => 'textarea', :attributes => {:id => 'content_text'}, :content => 'edited'
155 assert_tag :tag => 'input', :attributes => {:id => 'content_version', :value => '1'}
155 assert_tag :tag => 'input', :attributes => {:id => 'content_version', :value => '1'}
156 end
156 end
157
157
158 def test_update_stale_page_should_not_raise_an_error
159 @request.session[:user_id] = 2
160 c = Wiki.find(1).find_page('Another_page').content
161 c.text = 'Previous text'
162 c.save!
163 assert_equal 2, c.version
164
165 assert_no_difference 'WikiPage.count' do
166 assert_no_difference 'WikiContent.count' do
167 assert_no_difference 'WikiContent::Version.count' do
168 put :update, :project_id => 1,
169 :id => 'Another_page',
170 :content => {
171 :comments => 'My comments',
172 :text => 'Text should not be lost',
173 :version => 1
174 }
175 end
176 end
177 end
178 assert_response :success
179 assert_template 'edit'
180 assert_tag :div,
181 :attributes => { :class => /error/ },
182 :content => /Data has been updated by another user/
183 assert_tag 'textarea',
184 :attributes => { :name => 'content[text]' },
185 :content => /Text should not be lost/
186 assert_tag 'input',
187 :attributes => { :name => 'content[comments]', :value => 'My comments' }
188
189 c.reload
190 assert_equal 'Previous text', c.text
191 assert_equal 2, c.version
192 end
193
158 def test_preview
194 def test_preview
159 @request.session[:user_id] = 2
195 @request.session[:user_id] = 2
160 xhr :post, :preview, :project_id => 1, :id => 'CookBook_documentation',
196 xhr :post, :preview, :project_id => 1, :id => 'CookBook_documentation',
161 :content => { :comments => '',
197 :content => { :comments => '',
162 :text => 'this is a *previewed text*',
198 :text => 'this is a *previewed text*',
163 :version => 3 }
199 :version => 3 }
164 assert_response :success
200 assert_response :success
165 assert_template 'common/_preview'
201 assert_template 'common/_preview'
166 assert_tag :tag => 'strong', :content => /previewed text/
202 assert_tag :tag => 'strong', :content => /previewed text/
167 end
203 end
168
204
169 def test_preview_new_page
205 def test_preview_new_page
170 @request.session[:user_id] = 2
206 @request.session[:user_id] = 2
171 xhr :post, :preview, :project_id => 1, :id => 'New page',
207 xhr :post, :preview, :project_id => 1, :id => 'New page',
172 :content => { :text => 'h1. New page',
208 :content => { :text => 'h1. New page',
173 :comments => '',
209 :comments => '',
174 :version => 0 }
210 :version => 0 }
175 assert_response :success
211 assert_response :success
176 assert_template 'common/_preview'
212 assert_template 'common/_preview'
177 assert_tag :tag => 'h1', :content => /New page/
213 assert_tag :tag => 'h1', :content => /New page/
178 end
214 end
179
215
180 def test_history
216 def test_history
181 get :history, :project_id => 1, :id => 'CookBook_documentation'
217 get :history, :project_id => 1, :id => 'CookBook_documentation'
182 assert_response :success
218 assert_response :success
183 assert_template 'history'
219 assert_template 'history'
184 assert_not_nil assigns(:versions)
220 assert_not_nil assigns(:versions)
185 assert_equal 3, assigns(:versions).size
221 assert_equal 3, assigns(:versions).size
186 assert_select "input[type=submit][name=commit]"
222 assert_select "input[type=submit][name=commit]"
187 end
223 end
188
224
189 def test_history_with_one_version
225 def test_history_with_one_version
190 get :history, :project_id => 1, :id => 'Another_page'
226 get :history, :project_id => 1, :id => 'Another_page'
191 assert_response :success
227 assert_response :success
192 assert_template 'history'
228 assert_template 'history'
193 assert_not_nil assigns(:versions)
229 assert_not_nil assigns(:versions)
194 assert_equal 1, assigns(:versions).size
230 assert_equal 1, assigns(:versions).size
195 assert_select "input[type=submit][name=commit]", false
231 assert_select "input[type=submit][name=commit]", false
196 end
232 end
197
233
198 def test_diff
234 def test_diff
199 get :diff, :project_id => 1, :id => 'CookBook_documentation', :version => 2, :version_from => 1
235 get :diff, :project_id => 1, :id => 'CookBook_documentation', :version => 2, :version_from => 1
200 assert_response :success
236 assert_response :success
201 assert_template 'diff'
237 assert_template 'diff'
202 assert_tag :tag => 'span', :attributes => { :class => 'diff_in'},
238 assert_tag :tag => 'span', :attributes => { :class => 'diff_in'},
203 :content => /updated/
239 :content => /updated/
204 end
240 end
205
241
206 def test_annotate
242 def test_annotate
207 get :annotate, :project_id => 1, :id => 'CookBook_documentation', :version => 2
243 get :annotate, :project_id => 1, :id => 'CookBook_documentation', :version => 2
208 assert_response :success
244 assert_response :success
209 assert_template 'annotate'
245 assert_template 'annotate'
210 # Line 1
246 # Line 1
211 assert_tag :tag => 'tr', :child => { :tag => 'th', :attributes => {:class => 'line-num'}, :content => '1' },
247 assert_tag :tag => 'tr', :child => { :tag => 'th', :attributes => {:class => 'line-num'}, :content => '1' },
212 :child => { :tag => 'td', :attributes => {:class => 'author'}, :content => /John Smith/ },
248 :child => { :tag => 'td', :attributes => {:class => 'author'}, :content => /John Smith/ },
213 :child => { :tag => 'td', :content => /h1\. CookBook documentation/ }
249 :child => { :tag => 'td', :content => /h1\. CookBook documentation/ }
214 # Line 2
250 # Line 2
215 assert_tag :tag => 'tr', :child => { :tag => 'th', :attributes => {:class => 'line-num'}, :content => '2' },
251 assert_tag :tag => 'tr', :child => { :tag => 'th', :attributes => {:class => 'line-num'}, :content => '2' },
216 :child => { :tag => 'td', :attributes => {:class => 'author'}, :content => /redMine Admin/ },
252 :child => { :tag => 'td', :attributes => {:class => 'author'}, :content => /redMine Admin/ },
217 :child => { :tag => 'td', :content => /Some updated \[\[documentation\]\] here/ }
253 :child => { :tag => 'td', :content => /Some updated \[\[documentation\]\] here/ }
218 end
254 end
219
255
220 def test_get_rename
256 def test_get_rename
221 @request.session[:user_id] = 2
257 @request.session[:user_id] = 2
222 get :rename, :project_id => 1, :id => 'Another_page'
258 get :rename, :project_id => 1, :id => 'Another_page'
223 assert_response :success
259 assert_response :success
224 assert_template 'rename'
260 assert_template 'rename'
225 assert_tag 'option',
261 assert_tag 'option',
226 :attributes => {:value => ''},
262 :attributes => {:value => ''},
227 :content => '',
263 :content => '',
228 :parent => {:tag => 'select', :attributes => {:name => 'wiki_page[parent_id]'}}
264 :parent => {:tag => 'select', :attributes => {:name => 'wiki_page[parent_id]'}}
229 assert_no_tag 'option',
265 assert_no_tag 'option',
230 :attributes => {:selected => 'selected'},
266 :attributes => {:selected => 'selected'},
231 :parent => {:tag => 'select', :attributes => {:name => 'wiki_page[parent_id]'}}
267 :parent => {:tag => 'select', :attributes => {:name => 'wiki_page[parent_id]'}}
232 end
268 end
233
269
234 def test_get_rename_child_page
270 def test_get_rename_child_page
235 @request.session[:user_id] = 2
271 @request.session[:user_id] = 2
236 get :rename, :project_id => 1, :id => 'Child_1'
272 get :rename, :project_id => 1, :id => 'Child_1'
237 assert_response :success
273 assert_response :success
238 assert_template 'rename'
274 assert_template 'rename'
239 assert_tag 'option',
275 assert_tag 'option',
240 :attributes => {:value => ''},
276 :attributes => {:value => ''},
241 :content => '',
277 :content => '',
242 :parent => {:tag => 'select', :attributes => {:name => 'wiki_page[parent_id]'}}
278 :parent => {:tag => 'select', :attributes => {:name => 'wiki_page[parent_id]'}}
243 assert_tag 'option',
279 assert_tag 'option',
244 :attributes => {:value => '2', :selected => 'selected'},
280 :attributes => {:value => '2', :selected => 'selected'},
245 :content => /Another page/,
281 :content => /Another page/,
246 :parent => {
282 :parent => {
247 :tag => 'select',
283 :tag => 'select',
248 :attributes => {:name => 'wiki_page[parent_id]'}
284 :attributes => {:name => 'wiki_page[parent_id]'}
249 }
285 }
250 end
286 end
251
287
252 def test_rename_with_redirect
288 def test_rename_with_redirect
253 @request.session[:user_id] = 2
289 @request.session[:user_id] = 2
254 post :rename, :project_id => 1, :id => 'Another_page',
290 post :rename, :project_id => 1, :id => 'Another_page',
255 :wiki_page => { :title => 'Another renamed page',
291 :wiki_page => { :title => 'Another renamed page',
256 :redirect_existing_links => 1 }
292 :redirect_existing_links => 1 }
257 assert_redirected_to :action => 'show', :project_id => 'ecookbook', :id => 'Another_renamed_page'
293 assert_redirected_to :action => 'show', :project_id => 'ecookbook', :id => 'Another_renamed_page'
258 wiki = Project.find(1).wiki
294 wiki = Project.find(1).wiki
259 # Check redirects
295 # Check redirects
260 assert_not_nil wiki.find_page('Another page')
296 assert_not_nil wiki.find_page('Another page')
261 assert_nil wiki.find_page('Another page', :with_redirect => false)
297 assert_nil wiki.find_page('Another page', :with_redirect => false)
262 end
298 end
263
299
264 def test_rename_without_redirect
300 def test_rename_without_redirect
265 @request.session[:user_id] = 2
301 @request.session[:user_id] = 2
266 post :rename, :project_id => 1, :id => 'Another_page',
302 post :rename, :project_id => 1, :id => 'Another_page',
267 :wiki_page => { :title => 'Another renamed page',
303 :wiki_page => { :title => 'Another renamed page',
268 :redirect_existing_links => "0" }
304 :redirect_existing_links => "0" }
269 assert_redirected_to :action => 'show', :project_id => 'ecookbook', :id => 'Another_renamed_page'
305 assert_redirected_to :action => 'show', :project_id => 'ecookbook', :id => 'Another_renamed_page'
270 wiki = Project.find(1).wiki
306 wiki = Project.find(1).wiki
271 # Check that there's no redirects
307 # Check that there's no redirects
272 assert_nil wiki.find_page('Another page')
308 assert_nil wiki.find_page('Another page')
273 end
309 end
274
310
275 def test_rename_with_parent_assignment
311 def test_rename_with_parent_assignment
276 @request.session[:user_id] = 2
312 @request.session[:user_id] = 2
277 post :rename, :project_id => 1, :id => 'Another_page',
313 post :rename, :project_id => 1, :id => 'Another_page',
278 :wiki_page => { :title => 'Another page', :redirect_existing_links => "0", :parent_id => '4' }
314 :wiki_page => { :title => 'Another page', :redirect_existing_links => "0", :parent_id => '4' }
279 assert_redirected_to :action => 'show', :project_id => 'ecookbook', :id => 'Another_page'
315 assert_redirected_to :action => 'show', :project_id => 'ecookbook', :id => 'Another_page'
280 assert_equal WikiPage.find(4), WikiPage.find_by_title('Another_page').parent
316 assert_equal WikiPage.find(4), WikiPage.find_by_title('Another_page').parent
281 end
317 end
282
318
283 def test_rename_with_parent_unassignment
319 def test_rename_with_parent_unassignment
284 @request.session[:user_id] = 2
320 @request.session[:user_id] = 2
285 post :rename, :project_id => 1, :id => 'Child_1',
321 post :rename, :project_id => 1, :id => 'Child_1',
286 :wiki_page => { :title => 'Child 1', :redirect_existing_links => "0", :parent_id => '' }
322 :wiki_page => { :title => 'Child 1', :redirect_existing_links => "0", :parent_id => '' }
287 assert_redirected_to :action => 'show', :project_id => 'ecookbook', :id => 'Child_1'
323 assert_redirected_to :action => 'show', :project_id => 'ecookbook', :id => 'Child_1'
288 assert_nil WikiPage.find_by_title('Child_1').parent
324 assert_nil WikiPage.find_by_title('Child_1').parent
289 end
325 end
290
326
291 def test_destroy_child
327 def test_destroy_child
292 @request.session[:user_id] = 2
328 @request.session[:user_id] = 2
293 delete :destroy, :project_id => 1, :id => 'Child_1'
329 delete :destroy, :project_id => 1, :id => 'Child_1'
294 assert_redirected_to :action => 'index', :project_id => 'ecookbook'
330 assert_redirected_to :action => 'index', :project_id => 'ecookbook'
295 end
331 end
296
332
297 def test_destroy_parent
333 def test_destroy_parent
298 @request.session[:user_id] = 2
334 @request.session[:user_id] = 2
299 assert_no_difference('WikiPage.count') do
335 assert_no_difference('WikiPage.count') do
300 delete :destroy, :project_id => 1, :id => 'Another_page'
336 delete :destroy, :project_id => 1, :id => 'Another_page'
301 end
337 end
302 assert_response :success
338 assert_response :success
303 assert_template 'destroy'
339 assert_template 'destroy'
304 end
340 end
305
341
306 def test_destroy_parent_with_nullify
342 def test_destroy_parent_with_nullify
307 @request.session[:user_id] = 2
343 @request.session[:user_id] = 2
308 assert_difference('WikiPage.count', -1) do
344 assert_difference('WikiPage.count', -1) do
309 delete :destroy, :project_id => 1, :id => 'Another_page', :todo => 'nullify'
345 delete :destroy, :project_id => 1, :id => 'Another_page', :todo => 'nullify'
310 end
346 end
311 assert_redirected_to :action => 'index', :project_id => 'ecookbook'
347 assert_redirected_to :action => 'index', :project_id => 'ecookbook'
312 assert_nil WikiPage.find_by_id(2)
348 assert_nil WikiPage.find_by_id(2)
313 end
349 end
314
350
315 def test_destroy_parent_with_cascade
351 def test_destroy_parent_with_cascade
316 @request.session[:user_id] = 2
352 @request.session[:user_id] = 2
317 assert_difference('WikiPage.count', -3) do
353 assert_difference('WikiPage.count', -3) do
318 delete :destroy, :project_id => 1, :id => 'Another_page', :todo => 'destroy'
354 delete :destroy, :project_id => 1, :id => 'Another_page', :todo => 'destroy'
319 end
355 end
320 assert_redirected_to :action => 'index', :project_id => 'ecookbook'
356 assert_redirected_to :action => 'index', :project_id => 'ecookbook'
321 assert_nil WikiPage.find_by_id(2)
357 assert_nil WikiPage.find_by_id(2)
322 assert_nil WikiPage.find_by_id(5)
358 assert_nil WikiPage.find_by_id(5)
323 end
359 end
324
360
325 def test_destroy_parent_with_reassign
361 def test_destroy_parent_with_reassign
326 @request.session[:user_id] = 2
362 @request.session[:user_id] = 2
327 assert_difference('WikiPage.count', -1) do
363 assert_difference('WikiPage.count', -1) do
328 delete :destroy, :project_id => 1, :id => 'Another_page', :todo => 'reassign', :reassign_to_id => 1
364 delete :destroy, :project_id => 1, :id => 'Another_page', :todo => 'reassign', :reassign_to_id => 1
329 end
365 end
330 assert_redirected_to :action => 'index', :project_id => 'ecookbook'
366 assert_redirected_to :action => 'index', :project_id => 'ecookbook'
331 assert_nil WikiPage.find_by_id(2)
367 assert_nil WikiPage.find_by_id(2)
332 assert_equal WikiPage.find(1), WikiPage.find_by_id(5).parent
368 assert_equal WikiPage.find(1), WikiPage.find_by_id(5).parent
333 end
369 end
334
370
335 def test_index
371 def test_index
336 get :index, :project_id => 'ecookbook'
372 get :index, :project_id => 'ecookbook'
337 assert_response :success
373 assert_response :success
338 assert_template 'index'
374 assert_template 'index'
339 pages = assigns(:pages)
375 pages = assigns(:pages)
340 assert_not_nil pages
376 assert_not_nil pages
341 assert_equal Project.find(1).wiki.pages.size, pages.size
377 assert_equal Project.find(1).wiki.pages.size, pages.size
342 assert_equal pages.first.content.updated_on, pages.first.updated_on
378 assert_equal pages.first.content.updated_on, pages.first.updated_on
343
379
344 assert_tag :ul, :attributes => { :class => 'pages-hierarchy' },
380 assert_tag :ul, :attributes => { :class => 'pages-hierarchy' },
345 :child => { :tag => 'li', :child => { :tag => 'a', :attributes => { :href => '/projects/ecookbook/wiki/CookBook_documentation' },
381 :child => { :tag => 'li', :child => { :tag => 'a', :attributes => { :href => '/projects/ecookbook/wiki/CookBook_documentation' },
346 :content => 'CookBook documentation' },
382 :content => 'CookBook documentation' },
347 :child => { :tag => 'ul',
383 :child => { :tag => 'ul',
348 :child => { :tag => 'li',
384 :child => { :tag => 'li',
349 :child => { :tag => 'a', :attributes => { :href => '/projects/ecookbook/wiki/Page_with_an_inline_image' },
385 :child => { :tag => 'a', :attributes => { :href => '/projects/ecookbook/wiki/Page_with_an_inline_image' },
350 :content => 'Page with an inline image' } } } },
386 :content => 'Page with an inline image' } } } },
351 :child => { :tag => 'li', :child => { :tag => 'a', :attributes => { :href => '/projects/ecookbook/wiki/Another_page' },
387 :child => { :tag => 'li', :child => { :tag => 'a', :attributes => { :href => '/projects/ecookbook/wiki/Another_page' },
352 :content => 'Another page' } }
388 :content => 'Another page' } }
353 end
389 end
354
390
355 context "GET :export" do
391 context "GET :export" do
356 context "with an authorized user to export the wiki" do
392 context "with an authorized user to export the wiki" do
357 setup do
393 setup do
358 @request.session[:user_id] = 2
394 @request.session[:user_id] = 2
359 get :export, :project_id => 'ecookbook'
395 get :export, :project_id => 'ecookbook'
360 end
396 end
361
397
362 should_respond_with :success
398 should_respond_with :success
363 should_assign_to :pages
399 should_assign_to :pages
364 should_respond_with_content_type "text/html"
400 should_respond_with_content_type "text/html"
365 should "export all of the wiki pages to a single html file" do
401 should "export all of the wiki pages to a single html file" do
366 assert_select "a[name=?]", "CookBook_documentation"
402 assert_select "a[name=?]", "CookBook_documentation"
367 assert_select "a[name=?]", "Another_page"
403 assert_select "a[name=?]", "Another_page"
368 assert_select "a[name=?]", "Page_with_an_inline_image"
404 assert_select "a[name=?]", "Page_with_an_inline_image"
369 end
405 end
370
406
371 end
407 end
372
408
373 context "with an unauthorized user" do
409 context "with an unauthorized user" do
374 setup do
410 setup do
375 get :export, :project_id => 'ecookbook'
411 get :export, :project_id => 'ecookbook'
376
412
377 should_respond_with :redirect
413 should_respond_with :redirect
378 should_redirect_to('wiki index') { {:action => 'show', :project_id => @project, :id => nil} }
414 should_redirect_to('wiki index') { {:action => 'show', :project_id => @project, :id => nil} }
379 end
415 end
380 end
416 end
381 end
417 end
382
418
383 context "GET :date_index" do
419 context "GET :date_index" do
384 setup do
420 setup do
385 get :date_index, :project_id => 'ecookbook'
421 get :date_index, :project_id => 'ecookbook'
386 end
422 end
387
423
388 should_respond_with :success
424 should_respond_with :success
389 should_assign_to :pages
425 should_assign_to :pages
390 should_assign_to :pages_by_date
426 should_assign_to :pages_by_date
391 should_render_template 'wiki/date_index'
427 should_render_template 'wiki/date_index'
392
428
393 end
429 end
394
430
395 def test_not_found
431 def test_not_found
396 get :show, :project_id => 999
432 get :show, :project_id => 999
397 assert_response 404
433 assert_response 404
398 end
434 end
399
435
400 def test_protect_page
436 def test_protect_page
401 page = WikiPage.find_by_wiki_id_and_title(1, 'Another_page')
437 page = WikiPage.find_by_wiki_id_and_title(1, 'Another_page')
402 assert !page.protected?
438 assert !page.protected?
403 @request.session[:user_id] = 2
439 @request.session[:user_id] = 2
404 post :protect, :project_id => 1, :id => page.title, :protected => '1'
440 post :protect, :project_id => 1, :id => page.title, :protected => '1'
405 assert_redirected_to :action => 'show', :project_id => 'ecookbook', :id => 'Another_page'
441 assert_redirected_to :action => 'show', :project_id => 'ecookbook', :id => 'Another_page'
406 assert page.reload.protected?
442 assert page.reload.protected?
407 end
443 end
408
444
409 def test_unprotect_page
445 def test_unprotect_page
410 page = WikiPage.find_by_wiki_id_and_title(1, 'CookBook_documentation')
446 page = WikiPage.find_by_wiki_id_and_title(1, 'CookBook_documentation')
411 assert page.protected?
447 assert page.protected?
412 @request.session[:user_id] = 2
448 @request.session[:user_id] = 2
413 post :protect, :project_id => 1, :id => page.title, :protected => '0'
449 post :protect, :project_id => 1, :id => page.title, :protected => '0'
414 assert_redirected_to :action => 'show', :project_id => 'ecookbook', :id => 'CookBook_documentation'
450 assert_redirected_to :action => 'show', :project_id => 'ecookbook', :id => 'CookBook_documentation'
415 assert !page.reload.protected?
451 assert !page.reload.protected?
416 end
452 end
417
453
418 def test_show_page_with_edit_link
454 def test_show_page_with_edit_link
419 @request.session[:user_id] = 2
455 @request.session[:user_id] = 2
420 get :show, :project_id => 1
456 get :show, :project_id => 1
421 assert_response :success
457 assert_response :success
422 assert_template 'show'
458 assert_template 'show'
423 assert_tag :tag => 'a', :attributes => { :href => '/projects/1/wiki/CookBook_documentation/edit' }
459 assert_tag :tag => 'a', :attributes => { :href => '/projects/1/wiki/CookBook_documentation/edit' }
424 end
460 end
425
461
426 def test_show_page_without_edit_link
462 def test_show_page_without_edit_link
427 @request.session[:user_id] = 4
463 @request.session[:user_id] = 4
428 get :show, :project_id => 1
464 get :show, :project_id => 1
429 assert_response :success
465 assert_response :success
430 assert_template 'show'
466 assert_template 'show'
431 assert_no_tag :tag => 'a', :attributes => { :href => '/projects/1/wiki/CookBook_documentation/edit' }
467 assert_no_tag :tag => 'a', :attributes => { :href => '/projects/1/wiki/CookBook_documentation/edit' }
432 end
468 end
433
469
434 def test_edit_unprotected_page
470 def test_edit_unprotected_page
435 # Non members can edit unprotected wiki pages
471 # Non members can edit unprotected wiki pages
436 @request.session[:user_id] = 4
472 @request.session[:user_id] = 4
437 get :edit, :project_id => 1, :id => 'Another_page'
473 get :edit, :project_id => 1, :id => 'Another_page'
438 assert_response :success
474 assert_response :success
439 assert_template 'edit'
475 assert_template 'edit'
440 end
476 end
441
477
442 def test_edit_protected_page_by_nonmember
478 def test_edit_protected_page_by_nonmember
443 # Non members can't edit protected wiki pages
479 # Non members can't edit protected wiki pages
444 @request.session[:user_id] = 4
480 @request.session[:user_id] = 4
445 get :edit, :project_id => 1, :id => 'CookBook_documentation'
481 get :edit, :project_id => 1, :id => 'CookBook_documentation'
446 assert_response 403
482 assert_response 403
447 end
483 end
448
484
449 def test_edit_protected_page_by_member
485 def test_edit_protected_page_by_member
450 @request.session[:user_id] = 2
486 @request.session[:user_id] = 2
451 get :edit, :project_id => 1, :id => 'CookBook_documentation'
487 get :edit, :project_id => 1, :id => 'CookBook_documentation'
452 assert_response :success
488 assert_response :success
453 assert_template 'edit'
489 assert_template 'edit'
454 end
490 end
455
491
456 def test_history_of_non_existing_page_should_return_404
492 def test_history_of_non_existing_page_should_return_404
457 get :history, :project_id => 1, :id => 'Unknown_page'
493 get :history, :project_id => 1, :id => 'Unknown_page'
458 assert_response 404
494 assert_response 404
459 end
495 end
460 end
496 end
General Comments 0
You need to be logged in to leave comments. Login now