##// END OF EJS Templates
Adds #current_version? method to wiki content....
Jean-Philippe Lang -
r7852:b8a924e4e1cb
parent child
Show More
@@ -1,309 +1,309
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_or_new_page, :only => [:show, :edit, :update]
37 before_filter :find_existing_or_new_page, :only => [:show, :edit, :update]
38 before_filter :find_existing_page, :only => [:rename, :protect, :history, :diff, :annotate, :add_attachment, :destroy]
38 before_filter :find_existing_page, :only => [:rename, :protect, :history, :diff, :annotate, :add_attachment, :destroy]
39
39
40 helper :attachments
40 helper :attachments
41 include AttachmentsHelper
41 include AttachmentsHelper
42 helper :watchers
42 helper :watchers
43 include Redmine::Export::PDF
43 include Redmine::Export::PDF
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 if @page.new_record?
59 if @page.new_record?
60 if User.current.allowed_to?(:edit_wiki_pages, @project) && editable?
60 if User.current.allowed_to?(:edit_wiki_pages, @project) && editable?
61 edit
61 edit
62 render :action => 'edit'
62 render :action => 'edit'
63 else
63 else
64 render_404
64 render_404
65 end
65 end
66 return
66 return
67 end
67 end
68 if params[:version] && !User.current.allowed_to?(:view_wiki_edits, @project)
68 if params[:version] && !User.current.allowed_to?(:view_wiki_edits, @project)
69 # Redirects user to the current version if he's not allowed to view previous versions
69 # Redirects user to the current version if he's not allowed to view previous versions
70 redirect_to :version => nil
70 redirect_to :version => nil
71 return
71 return
72 end
72 end
73 @content = @page.content_for_version(params[:version])
73 @content = @page.content_for_version(params[:version])
74 if User.current.allowed_to?(:export_wiki_pages, @project)
74 if User.current.allowed_to?(:export_wiki_pages, @project)
75 if params[:format] == 'pdf'
75 if params[:format] == 'pdf'
76 send_data(wiki_to_pdf(@page, @project), :type => 'application/pdf', :filename => "#{@page.title}.pdf")
76 send_data(wiki_to_pdf(@page, @project), :type => 'application/pdf', :filename => "#{@page.title}.pdf")
77 return
77 return
78 elsif params[:format] == 'html'
78 elsif params[:format] == 'html'
79 export = render_to_string :action => 'export', :layout => false
79 export = render_to_string :action => 'export', :layout => false
80 send_data(export, :type => 'text/html', :filename => "#{@page.title}.html")
80 send_data(export, :type => 'text/html', :filename => "#{@page.title}.html")
81 return
81 return
82 elsif params[:format] == 'txt'
82 elsif params[:format] == 'txt'
83 send_data(@content.text, :type => 'text/plain', :filename => "#{@page.title}.txt")
83 send_data(@content.text, :type => 'text/plain', :filename => "#{@page.title}.txt")
84 return
84 return
85 end
85 end
86 end
86 end
87 @editable = editable?
87 @editable = editable?
88 @sections_editable = @editable && User.current.allowed_to?(:edit_wiki_pages, @page.project) &&
88 @sections_editable = @editable && User.current.allowed_to?(:edit_wiki_pages, @page.project) &&
89 @content.version == @page.content.version &&
89 @content.current_version? &&
90 Redmine::WikiFormatting.supports_section_edit?
90 Redmine::WikiFormatting.supports_section_edit?
91
91
92 render :action => 'show'
92 render :action => 'show'
93 end
93 end
94
94
95 # edit an existing page or a new one
95 # edit an existing page or a new one
96 def edit
96 def edit
97 return render_403 unless editable?
97 return render_403 unless editable?
98 @page.content = WikiContent.new(:page => @page) if @page.new_record?
98 @page.content = WikiContent.new(:page => @page) if @page.new_record?
99
99
100 @content = @page.content_for_version(params[:version])
100 @content = @page.content_for_version(params[:version])
101 @content.text = initial_page_content(@page) if @content.text.blank?
101 @content.text = initial_page_content(@page) if @content.text.blank?
102 # don't keep previous comment
102 # don't keep previous comment
103 @content.comments = nil
103 @content.comments = nil
104
104
105 # To prevent StaleObjectError exception when reverting to a previous version
105 # To prevent StaleObjectError exception when reverting to a previous version
106 @content.version = @page.content.version
106 @content.version = @page.content.version
107
107
108 @text = @content.text
108 @text = @content.text
109 if params[:section].present? && Redmine::WikiFormatting.supports_section_edit?
109 if params[:section].present? && Redmine::WikiFormatting.supports_section_edit?
110 @section = params[:section].to_i
110 @section = params[:section].to_i
111 @text, @section_hash = Redmine::WikiFormatting.formatter.new(@text).get_section(@section)
111 @text, @section_hash = Redmine::WikiFormatting.formatter.new(@text).get_section(@section)
112 render_404 if @text.blank?
112 render_404 if @text.blank?
113 end
113 end
114 end
114 end
115
115
116 verify :method => :put, :only => :update, :render => {:nothing => true, :status => :method_not_allowed }
116 verify :method => :put, :only => :update, :render => {:nothing => true, :status => :method_not_allowed }
117 # Creates a new page or updates an existing one
117 # Creates a new page or updates an existing one
118 def update
118 def update
119 return render_403 unless editable?
119 return render_403 unless editable?
120 @page.content = WikiContent.new(:page => @page) if @page.new_record?
120 @page.content = WikiContent.new(:page => @page) if @page.new_record?
121
121
122 @content = @page.content_for_version(params[:version])
122 @content = @page.content_for_version(params[:version])
123 @content.text = initial_page_content(@page) if @content.text.blank?
123 @content.text = initial_page_content(@page) if @content.text.blank?
124 # don't keep previous comment
124 # don't keep previous comment
125 @content.comments = nil
125 @content.comments = nil
126
126
127 if !@page.new_record? && params[:content].present? && @content.text == params[:content][:text]
127 if !@page.new_record? && params[:content].present? && @content.text == params[:content][:text]
128 attachments = Attachment.attach_files(@page, params[:attachments])
128 attachments = Attachment.attach_files(@page, params[:attachments])
129 render_attachment_warning_if_needed(@page)
129 render_attachment_warning_if_needed(@page)
130 # don't save if text wasn't changed
130 # don't save if text wasn't changed
131 redirect_to :action => 'show', :project_id => @project, :id => @page.title
131 redirect_to :action => 'show', :project_id => @project, :id => @page.title
132 return
132 return
133 end
133 end
134
134
135 @content.comments = params[:content][:comments]
135 @content.comments = params[:content][:comments]
136 @text = params[:content][:text]
136 @text = params[:content][:text]
137 if params[:section].present? && Redmine::WikiFormatting.supports_section_edit?
137 if params[:section].present? && Redmine::WikiFormatting.supports_section_edit?
138 @section = params[:section].to_i
138 @section = params[:section].to_i
139 @section_hash = params[:section_hash]
139 @section_hash = params[:section_hash]
140 @content.text = Redmine::WikiFormatting.formatter.new(@content.text).update_section(params[:section].to_i, @text, @section_hash)
140 @content.text = Redmine::WikiFormatting.formatter.new(@content.text).update_section(params[:section].to_i, @text, @section_hash)
141 else
141 else
142 @content.version = params[:content][:version]
142 @content.version = params[:content][:version]
143 @content.text = @text
143 @content.text = @text
144 end
144 end
145 @content.author = User.current
145 @content.author = User.current
146 # if page is new @page.save will also save content, but not if page isn't a new record
146 # if page is new @page.save will also save content, but not if page isn't a new record
147 if (@page.new_record? ? @page.save : @content.save)
147 if (@page.new_record? ? @page.save : @content.save)
148 attachments = Attachment.attach_files(@page, params[:attachments])
148 attachments = Attachment.attach_files(@page, params[:attachments])
149 render_attachment_warning_if_needed(@page)
149 render_attachment_warning_if_needed(@page)
150 call_hook(:controller_wiki_edit_after_save, { :params => params, :page => @page})
150 call_hook(:controller_wiki_edit_after_save, { :params => params, :page => @page})
151 redirect_to :action => 'show', :project_id => @project, :id => @page.title
151 redirect_to :action => 'show', :project_id => @project, :id => @page.title
152 else
152 else
153 render :action => 'edit'
153 render :action => 'edit'
154 end
154 end
155
155
156 rescue ActiveRecord::StaleObjectError, Redmine::WikiFormatting::StaleSectionError
156 rescue ActiveRecord::StaleObjectError, Redmine::WikiFormatting::StaleSectionError
157 # Optimistic locking exception
157 # Optimistic locking exception
158 flash.now[:error] = l(:notice_locking_conflict)
158 flash.now[:error] = l(:notice_locking_conflict)
159 render :action => 'edit'
159 render :action => 'edit'
160 end
160 end
161
161
162 # rename a page
162 # rename a page
163 def rename
163 def rename
164 return render_403 unless editable?
164 return render_403 unless editable?
165 @page.redirect_existing_links = true
165 @page.redirect_existing_links = true
166 # used to display the *original* title if some AR validation errors occur
166 # used to display the *original* title if some AR validation errors occur
167 @original_title = @page.pretty_title
167 @original_title = @page.pretty_title
168 if request.post? && @page.update_attributes(params[:wiki_page])
168 if request.post? && @page.update_attributes(params[:wiki_page])
169 flash[:notice] = l(:notice_successful_update)
169 flash[:notice] = l(:notice_successful_update)
170 redirect_to :action => 'show', :project_id => @project, :id => @page.title
170 redirect_to :action => 'show', :project_id => @project, :id => @page.title
171 end
171 end
172 end
172 end
173
173
174 verify :method => :post, :only => :protect, :redirect_to => { :action => :show }
174 verify :method => :post, :only => :protect, :redirect_to => { :action => :show }
175 def protect
175 def protect
176 @page.update_attribute :protected, params[:protected]
176 @page.update_attribute :protected, params[:protected]
177 redirect_to :action => 'show', :project_id => @project, :id => @page.title
177 redirect_to :action => 'show', :project_id => @project, :id => @page.title
178 end
178 end
179
179
180 # show page history
180 # show page history
181 def history
181 def history
182 @version_count = @page.content.versions.count
182 @version_count = @page.content.versions.count
183 @version_pages = Paginator.new self, @version_count, per_page_option, params['p']
183 @version_pages = Paginator.new self, @version_count, per_page_option, params['p']
184 # don't load text
184 # don't load text
185 @versions = @page.content.versions.find :all,
185 @versions = @page.content.versions.find :all,
186 :select => "id, author_id, comments, updated_on, version",
186 :select => "id, author_id, comments, updated_on, version",
187 :order => 'version DESC',
187 :order => 'version DESC',
188 :limit => @version_pages.items_per_page + 1,
188 :limit => @version_pages.items_per_page + 1,
189 :offset => @version_pages.current.offset
189 :offset => @version_pages.current.offset
190
190
191 render :layout => false if request.xhr?
191 render :layout => false if request.xhr?
192 end
192 end
193
193
194 def diff
194 def diff
195 @diff = @page.diff(params[:version], params[:version_from])
195 @diff = @page.diff(params[:version], params[:version_from])
196 render_404 unless @diff
196 render_404 unless @diff
197 end
197 end
198
198
199 def annotate
199 def annotate
200 @annotate = @page.annotate(params[:version])
200 @annotate = @page.annotate(params[:version])
201 render_404 unless @annotate
201 render_404 unless @annotate
202 end
202 end
203
203
204 verify :method => :delete, :only => [:destroy], :redirect_to => { :action => :show }
204 verify :method => :delete, :only => [:destroy], :redirect_to => { :action => :show }
205 # Removes a wiki page and its history
205 # Removes a wiki page and its history
206 # Children can be either set as root pages, removed or reassigned to another parent page
206 # Children can be either set as root pages, removed or reassigned to another parent page
207 def destroy
207 def destroy
208 return render_403 unless editable?
208 return render_403 unless editable?
209
209
210 @descendants_count = @page.descendants.size
210 @descendants_count = @page.descendants.size
211 if @descendants_count > 0
211 if @descendants_count > 0
212 case params[:todo]
212 case params[:todo]
213 when 'nullify'
213 when 'nullify'
214 # Nothing to do
214 # Nothing to do
215 when 'destroy'
215 when 'destroy'
216 # Removes all its descendants
216 # Removes all its descendants
217 @page.descendants.each(&:destroy)
217 @page.descendants.each(&:destroy)
218 when 'reassign'
218 when 'reassign'
219 # Reassign children to another parent page
219 # Reassign children to another parent page
220 reassign_to = @wiki.pages.find_by_id(params[:reassign_to_id].to_i)
220 reassign_to = @wiki.pages.find_by_id(params[:reassign_to_id].to_i)
221 return unless reassign_to
221 return unless reassign_to
222 @page.children.each do |child|
222 @page.children.each do |child|
223 child.update_attribute(:parent, reassign_to)
223 child.update_attribute(:parent, reassign_to)
224 end
224 end
225 else
225 else
226 @reassignable_to = @wiki.pages - @page.self_and_descendants
226 @reassignable_to = @wiki.pages - @page.self_and_descendants
227 return
227 return
228 end
228 end
229 end
229 end
230 @page.destroy
230 @page.destroy
231 redirect_to :action => 'index', :project_id => @project
231 redirect_to :action => 'index', :project_id => @project
232 end
232 end
233
233
234 # Export wiki to a single html file
234 # Export wiki to a single html file
235 def export
235 def export
236 if User.current.allowed_to?(:export_wiki_pages, @project)
236 if User.current.allowed_to?(:export_wiki_pages, @project)
237 @pages = @wiki.pages.find :all, :order => 'title'
237 @pages = @wiki.pages.find :all, :order => 'title'
238 export = render_to_string :action => 'export_multiple', :layout => false
238 export = render_to_string :action => 'export_multiple', :layout => false
239 send_data(export, :type => 'text/html', :filename => "wiki.html")
239 send_data(export, :type => 'text/html', :filename => "wiki.html")
240 else
240 else
241 redirect_to :action => 'show', :project_id => @project, :id => nil
241 redirect_to :action => 'show', :project_id => @project, :id => nil
242 end
242 end
243 end
243 end
244
244
245 def preview
245 def preview
246 page = @wiki.find_page(params[:id])
246 page = @wiki.find_page(params[:id])
247 # page is nil when previewing a new page
247 # page is nil when previewing a new page
248 return render_403 unless page.nil? || editable?(page)
248 return render_403 unless page.nil? || editable?(page)
249 if page
249 if page
250 @attachements = page.attachments
250 @attachements = page.attachments
251 @previewed = page.content
251 @previewed = page.content
252 end
252 end
253 @text = params[:content][:text]
253 @text = params[:content][:text]
254 render :partial => 'common/preview'
254 render :partial => 'common/preview'
255 end
255 end
256
256
257 def add_attachment
257 def add_attachment
258 return render_403 unless editable?
258 return render_403 unless editable?
259 attachments = Attachment.attach_files(@page, params[:attachments])
259 attachments = Attachment.attach_files(@page, params[:attachments])
260 render_attachment_warning_if_needed(@page)
260 render_attachment_warning_if_needed(@page)
261 redirect_to :action => 'show', :id => @page.title, :project_id => @project
261 redirect_to :action => 'show', :id => @page.title, :project_id => @project
262 end
262 end
263
263
264 private
264 private
265
265
266 def find_wiki
266 def find_wiki
267 @project = Project.find(params[:project_id])
267 @project = Project.find(params[:project_id])
268 @wiki = @project.wiki
268 @wiki = @project.wiki
269 render_404 unless @wiki
269 render_404 unless @wiki
270 rescue ActiveRecord::RecordNotFound
270 rescue ActiveRecord::RecordNotFound
271 render_404
271 render_404
272 end
272 end
273
273
274 # Finds the requested page or a new page if it doesn't exist
274 # Finds the requested page or a new page if it doesn't exist
275 def find_existing_or_new_page
275 def find_existing_or_new_page
276 @page = @wiki.find_or_new_page(params[:id])
276 @page = @wiki.find_or_new_page(params[:id])
277 if @wiki.page_found_with_redirect?
277 if @wiki.page_found_with_redirect?
278 redirect_to params.update(:id => @page.title)
278 redirect_to params.update(:id => @page.title)
279 end
279 end
280 end
280 end
281
281
282 # Finds the requested page and returns a 404 error if it doesn't exist
282 # Finds the requested page and returns a 404 error if it doesn't exist
283 def find_existing_page
283 def find_existing_page
284 @page = @wiki.find_page(params[:id])
284 @page = @wiki.find_page(params[:id])
285 if @page.nil?
285 if @page.nil?
286 render_404
286 render_404
287 return
287 return
288 end
288 end
289 if @wiki.page_found_with_redirect?
289 if @wiki.page_found_with_redirect?
290 redirect_to params.update(:id => @page.title)
290 redirect_to params.update(:id => @page.title)
291 end
291 end
292 end
292 end
293
293
294 # Returns true if the current user is allowed to edit the page, otherwise false
294 # Returns true if the current user is allowed to edit the page, otherwise false
295 def editable?(page = @page)
295 def editable?(page = @page)
296 page.editable_by?(User.current)
296 page.editable_by?(User.current)
297 end
297 end
298
298
299 # Returns the default content of a new wiki page
299 # Returns the default content of a new wiki page
300 def initial_page_content(page)
300 def initial_page_content(page)
301 helper = Redmine::WikiFormatting.helper_for(Setting.text_formatting)
301 helper = Redmine::WikiFormatting.helper_for(Setting.text_formatting)
302 extend helper unless self.instance_of?(helper)
302 extend helper unless self.instance_of?(helper)
303 helper.instance_method(:initial_page_content).bind(self).call(page)
303 helper.instance_method(:initial_page_content).bind(self).call(page)
304 end
304 end
305
305
306 def load_pages_for_index
306 def load_pages_for_index
307 @pages = @wiki.pages.with_updated_on.all(:order => 'title', :include => {:wiki => :project})
307 @pages = @wiki.pages.with_updated_on.all(:order => 'title', :include => {:wiki => :project})
308 end
308 end
309 end
309 end
@@ -1,112 +1,122
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 'zlib'
18 require 'zlib'
19
19
20 class WikiContent < ActiveRecord::Base
20 class WikiContent < ActiveRecord::Base
21 set_locking_column :version
21 set_locking_column :version
22 belongs_to :page, :class_name => 'WikiPage', :foreign_key => 'page_id'
22 belongs_to :page, :class_name => 'WikiPage', :foreign_key => 'page_id'
23 belongs_to :author, :class_name => 'User', :foreign_key => 'author_id'
23 belongs_to :author, :class_name => 'User', :foreign_key => 'author_id'
24 validates_presence_of :text
24 validates_presence_of :text
25 validates_length_of :comments, :maximum => 255, :allow_nil => true
25 validates_length_of :comments, :maximum => 255, :allow_nil => true
26
26
27 acts_as_versioned
27 acts_as_versioned
28
28
29 def visible?(user=User.current)
29 def visible?(user=User.current)
30 page.visible?(user)
30 page.visible?(user)
31 end
31 end
32
32
33 def project
33 def project
34 page.project
34 page.project
35 end
35 end
36
36
37 def attachments
37 def attachments
38 page.nil? ? [] : page.attachments
38 page.nil? ? [] : page.attachments
39 end
39 end
40
40
41 # Returns the mail adresses of users that should be notified
41 # Returns the mail adresses of users that should be notified
42 def recipients
42 def recipients
43 notified = project.notified_users
43 notified = project.notified_users
44 notified.reject! {|user| !visible?(user)}
44 notified.reject! {|user| !visible?(user)}
45 notified.collect(&:mail)
45 notified.collect(&:mail)
46 end
46 end
47
47
48 # Return true if the content is the current page content
49 def current_version?
50 true
51 end
52
48 class Version
53 class Version
49 belongs_to :page, :class_name => '::WikiPage', :foreign_key => 'page_id'
54 belongs_to :page, :class_name => '::WikiPage', :foreign_key => 'page_id'
50 belongs_to :author, :class_name => '::User', :foreign_key => 'author_id'
55 belongs_to :author, :class_name => '::User', :foreign_key => 'author_id'
51 attr_protected :data
56 attr_protected :data
52
57
53 acts_as_event :title => Proc.new {|o| "#{l(:label_wiki_edit)}: #{o.page.title} (##{o.version})"},
58 acts_as_event :title => Proc.new {|o| "#{l(:label_wiki_edit)}: #{o.page.title} (##{o.version})"},
54 :description => :comments,
59 :description => :comments,
55 :datetime => :updated_on,
60 :datetime => :updated_on,
56 :type => 'wiki-page',
61 :type => 'wiki-page',
57 :url => Proc.new {|o| {:controller => 'wiki', :action => 'show', :project_id => o.page.wiki.project, :id => o.page.title, :version => o.version}}
62 :url => Proc.new {|o| {:controller => 'wiki', :action => 'show', :project_id => o.page.wiki.project, :id => o.page.title, :version => o.version}}
58
63
59 acts_as_activity_provider :type => 'wiki_edits',
64 acts_as_activity_provider :type => 'wiki_edits',
60 :timestamp => "#{WikiContent.versioned_table_name}.updated_on",
65 :timestamp => "#{WikiContent.versioned_table_name}.updated_on",
61 :author_key => "#{WikiContent.versioned_table_name}.author_id",
66 :author_key => "#{WikiContent.versioned_table_name}.author_id",
62 :permission => :view_wiki_edits,
67 :permission => :view_wiki_edits,
63 :find_options => {:select => "#{WikiContent.versioned_table_name}.updated_on, #{WikiContent.versioned_table_name}.comments, " +
68 :find_options => {:select => "#{WikiContent.versioned_table_name}.updated_on, #{WikiContent.versioned_table_name}.comments, " +
64 "#{WikiContent.versioned_table_name}.#{WikiContent.version_column}, #{WikiPage.table_name}.title, " +
69 "#{WikiContent.versioned_table_name}.#{WikiContent.version_column}, #{WikiPage.table_name}.title, " +
65 "#{WikiContent.versioned_table_name}.page_id, #{WikiContent.versioned_table_name}.author_id, " +
70 "#{WikiContent.versioned_table_name}.page_id, #{WikiContent.versioned_table_name}.author_id, " +
66 "#{WikiContent.versioned_table_name}.id",
71 "#{WikiContent.versioned_table_name}.id",
67 :joins => "LEFT JOIN #{WikiPage.table_name} ON #{WikiPage.table_name}.id = #{WikiContent.versioned_table_name}.page_id " +
72 :joins => "LEFT JOIN #{WikiPage.table_name} ON #{WikiPage.table_name}.id = #{WikiContent.versioned_table_name}.page_id " +
68 "LEFT JOIN #{Wiki.table_name} ON #{Wiki.table_name}.id = #{WikiPage.table_name}.wiki_id " +
73 "LEFT JOIN #{Wiki.table_name} ON #{Wiki.table_name}.id = #{WikiPage.table_name}.wiki_id " +
69 "LEFT JOIN #{Project.table_name} ON #{Project.table_name}.id = #{Wiki.table_name}.project_id"}
74 "LEFT JOIN #{Project.table_name} ON #{Project.table_name}.id = #{Wiki.table_name}.project_id"}
70
75
71 def text=(plain)
76 def text=(plain)
72 case Setting.wiki_compression
77 case Setting.wiki_compression
73 when 'gzip'
78 when 'gzip'
74 begin
79 begin
75 self.data = Zlib::Deflate.deflate(plain, Zlib::BEST_COMPRESSION)
80 self.data = Zlib::Deflate.deflate(plain, Zlib::BEST_COMPRESSION)
76 self.compression = 'gzip'
81 self.compression = 'gzip'
77 rescue
82 rescue
78 self.data = plain
83 self.data = plain
79 self.compression = ''
84 self.compression = ''
80 end
85 end
81 else
86 else
82 self.data = plain
87 self.data = plain
83 self.compression = ''
88 self.compression = ''
84 end
89 end
85 plain
90 plain
86 end
91 end
87
92
88 def text
93 def text
89 @text ||= case compression
94 @text ||= case compression
90 when 'gzip'
95 when 'gzip'
91 str = Zlib::Inflate.inflate(data)
96 str = Zlib::Inflate.inflate(data)
92 str.force_encoding("UTF-8") if str.respond_to?(:force_encoding)
97 str.force_encoding("UTF-8") if str.respond_to?(:force_encoding)
93 str
98 str
94 else
99 else
95 # uncompressed data
100 # uncompressed data
96 data
101 data
97 end
102 end
98 end
103 end
99
104
100 def project
105 def project
101 page.project
106 page.project
102 end
107 end
103
108
109 # Return true if the content is the current page content
110 def current_version?
111 page.content.version == self.version
112 end
113
104 # Returns the previous version or nil
114 # Returns the previous version or nil
105 def previous
115 def previous
106 @previous ||= WikiContent::Version.find(:first,
116 @previous ||= WikiContent::Version.find(:first,
107 :order => 'version DESC',
117 :order => 'version DESC',
108 :include => :author,
118 :include => :author,
109 :conditions => ["wiki_content_id = ? AND version < ?", wiki_content_id, version])
119 :conditions => ["wiki_content_id = ? AND version < ?", wiki_content_id, version])
110 end
120 end
111 end
121 end
112 end
122 end
@@ -1,69 +1,69
1 <div class="contextual">
1 <div class="contextual">
2 <% if @editable %>
2 <% if @editable %>
3 <%= link_to_if_authorized(l(:button_edit), {:action => 'edit', :id => @page.title}, :class => 'icon icon-edit', :accesskey => accesskey(:edit)) if @content.version == @page.content.version %>
3 <%= link_to_if_authorized(l(:button_edit), {:action => 'edit', :id => @page.title}, :class => 'icon icon-edit', :accesskey => accesskey(:edit)) if @content.current_version? %>
4 <%= watcher_tag(@page, User.current) %>
4 <%= watcher_tag(@page, User.current) %>
5 <%= link_to_if_authorized(l(:button_lock), {:action => 'protect', :id => @page.title, :protected => 1}, :method => :post, :class => 'icon icon-lock') if !@page.protected? %>
5 <%= link_to_if_authorized(l(:button_lock), {:action => 'protect', :id => @page.title, :protected => 1}, :method => :post, :class => 'icon icon-lock') if !@page.protected? %>
6 <%= link_to_if_authorized(l(:button_unlock), {:action => 'protect', :id => @page.title, :protected => 0}, :method => :post, :class => 'icon icon-unlock') if @page.protected? %>
6 <%= link_to_if_authorized(l(:button_unlock), {:action => 'protect', :id => @page.title, :protected => 0}, :method => :post, :class => 'icon icon-unlock') if @page.protected? %>
7 <%= link_to_if_authorized(l(:button_rename), {:action => 'rename', :id => @page.title}, :class => 'icon icon-move') if @content.version == @page.content.version %>
7 <%= link_to_if_authorized(l(:button_rename), {:action => 'rename', :id => @page.title}, :class => 'icon icon-move') if @content.current_version? %>
8 <%= link_to_if_authorized(l(:button_delete), {:action => 'destroy', :id => @page.title}, :method => :delete, :confirm => l(:text_are_you_sure), :class => 'icon icon-del') %>
8 <%= link_to_if_authorized(l(:button_delete), {:action => 'destroy', :id => @page.title}, :method => :delete, :confirm => l(:text_are_you_sure), :class => 'icon icon-del') %>
9 <%= link_to_if_authorized(l(:button_rollback), {:action => 'edit', :id => @page.title, :version => @content.version }, :class => 'icon icon-cancel') if @content.version < @page.content.version %>
9 <%= link_to_if_authorized(l(:button_rollback), {:action => 'edit', :id => @page.title, :version => @content.version }, :class => 'icon icon-cancel') unless @content.current_version? %>
10 <% end %>
10 <% end %>
11 <%= link_to_if_authorized(l(:label_history), {:action => 'history', :id => @page.title}, :class => 'icon icon-history') %>
11 <%= link_to_if_authorized(l(:label_history), {:action => 'history', :id => @page.title}, :class => 'icon icon-history') %>
12 </div>
12 </div>
13
13
14 <%= wiki_page_breadcrumb(@page) %>
14 <%= wiki_page_breadcrumb(@page) %>
15
15
16 <% if @content.version != @page.content.version %>
16 <% unless @content.current_version? %>
17 <p>
17 <p>
18 <%= link_to(("\xc2\xab " + l(:label_previous)),
18 <%= link_to(("\xc2\xab " + l(:label_previous)),
19 :action => 'show', :id => @page.title, :project_id => @page.project,
19 :action => 'show', :id => @page.title, :project_id => @page.project,
20 :version => (@content.version - 1)) + " - " if @content.version > 1 %>
20 :version => (@content.version - 1)) + " - " if @content.version > 1 %>
21 <%= "#{l(:label_version)} #{@content.version}/#{@page.content.version}" %>
21 <%= "#{l(:label_version)} #{@content.version}/#{@page.content.version}" %>
22 <%= '(' + link_to(l(:label_diff), :controller => 'wiki', :action => 'diff',
22 <%= '(' + link_to(l(:label_diff), :controller => 'wiki', :action => 'diff',
23 :id => @page.title, :project_id => @page.project,
23 :id => @page.title, :project_id => @page.project,
24 :version => @content.version) + ')' if @content.version > 1 %> -
24 :version => @content.version) + ')' if @content.version > 1 %> -
25 <%= link_to((l(:label_next) + " \xc2\xbb"), :action => 'show',
25 <%= link_to((l(:label_next) + " \xc2\xbb"), :action => 'show',
26 :id => @page.title, :project_id => @page.project,
26 :id => @page.title, :project_id => @page.project,
27 :version => (@content.version + 1)) + " - " if @content.version < @page.content.version %>
27 :version => (@content.version + 1)) + " - " if @content.version < @page.content.version %>
28 <%= link_to(l(:label_current_version), :action => 'show', :id => @page.title, :project_id => @page.project) %>
28 <%= link_to(l(:label_current_version), :action => 'show', :id => @page.title, :project_id => @page.project) %>
29 <br />
29 <br />
30 <em><%= @content.author ? link_to_user(@content.author) : l(:label_user_anonymous)
30 <em><%= @content.author ? link_to_user(@content.author) : l(:label_user_anonymous)
31 %>, <%= format_time(@content.updated_on) %> </em><br />
31 %>, <%= format_time(@content.updated_on) %> </em><br />
32 <%=h @content.comments %>
32 <%=h @content.comments %>
33 </p>
33 </p>
34 <hr />
34 <hr />
35 <% end %>
35 <% end %>
36
36
37 <%= render(:partial => "wiki/content", :locals => {:content => @content}) %>
37 <%= render(:partial => "wiki/content", :locals => {:content => @content}) %>
38
38
39 <%= link_to_attachments @page %>
39 <%= link_to_attachments @page %>
40
40
41 <% if @editable && authorize_for('wiki', 'add_attachment') %>
41 <% if @editable && authorize_for('wiki', 'add_attachment') %>
42 <div id="wiki_add_attachment">
42 <div id="wiki_add_attachment">
43 <p><%= link_to l(:label_attachment_new), {}, :onclick => "Element.show('add_attachment_form'); Element.hide(this); Element.scrollTo('add_attachment_form'); return false;",
43 <p><%= link_to l(:label_attachment_new), {}, :onclick => "Element.show('add_attachment_form'); Element.hide(this); Element.scrollTo('add_attachment_form'); return false;",
44 :id => 'attach_files_link' %></p>
44 :id => 'attach_files_link' %></p>
45 <% form_tag({ :controller => 'wiki', :action => 'add_attachment', :project_id => @project, :id => @page.title }, :multipart => true, :id => "add_attachment_form", :style => "display:none;") do %>
45 <% form_tag({ :controller => 'wiki', :action => 'add_attachment', :project_id => @project, :id => @page.title }, :multipart => true, :id => "add_attachment_form", :style => "display:none;") do %>
46 <div class="box">
46 <div class="box">
47 <p><%= render :partial => 'attachments/form' %></p>
47 <p><%= render :partial => 'attachments/form' %></p>
48 </div>
48 </div>
49 <%= submit_tag l(:button_add) %>
49 <%= submit_tag l(:button_add) %>
50 <%= link_to l(:button_cancel), {}, :onclick => "Element.hide('add_attachment_form'); Element.show('attach_files_link'); return false;" %>
50 <%= link_to l(:button_cancel), {}, :onclick => "Element.hide('add_attachment_form'); Element.show('attach_files_link'); return false;" %>
51 <% end %>
51 <% end %>
52 </div>
52 </div>
53 <% end %>
53 <% end %>
54
54
55 <% other_formats_links do |f| %>
55 <% other_formats_links do |f| %>
56 <%= f.link_to 'PDF', :url => {:id => @page.title, :version => params[:version]} %>
56 <%= f.link_to 'PDF', :url => {:id => @page.title, :version => params[:version]} %>
57 <%= f.link_to 'HTML', :url => {:id => @page.title, :version => params[:version]} %>
57 <%= f.link_to 'HTML', :url => {:id => @page.title, :version => params[:version]} %>
58 <%= f.link_to 'TXT', :url => {:id => @page.title, :version => params[:version]} %>
58 <%= f.link_to 'TXT', :url => {:id => @page.title, :version => params[:version]} %>
59 <% end if User.current.allowed_to?(:export_wiki_pages, @project) %>
59 <% end if User.current.allowed_to?(:export_wiki_pages, @project) %>
60
60
61 <% content_for :header_tags do %>
61 <% content_for :header_tags do %>
62 <%= stylesheet_link_tag 'scm' %>
62 <%= stylesheet_link_tag 'scm' %>
63 <% end %>
63 <% end %>
64
64
65 <% content_for :sidebar do %>
65 <% content_for :sidebar do %>
66 <%= render :partial => 'sidebar' %>
66 <%= render :partial => 'sidebar' %>
67 <% end %>
67 <% end %>
68
68
69 <% html_title @page.pretty_title %>
69 <% html_title @page.pretty_title %>
@@ -1,78 +1,102
1 ---
1 ---
2 wiki_content_versions_001:
2 wiki_content_versions_001:
3 updated_on: 2007-03-07 00:08:07 +01:00
3 updated_on: 2007-03-07 00:08:07 +01:00
4 page_id: 1
4 page_id: 1
5 id: 1
5 id: 1
6 version: 1
6 version: 1
7 author_id: 2
7 author_id: 2
8 comments: Page creation
8 comments: Page creation
9 wiki_content_id: 1
9 wiki_content_id: 1
10 compression: ""
10 compression: ""
11 data: |-
11 data: |-
12 h1. CookBook documentation
12 h1. CookBook documentation
13
13
14
14
15
15
16 Some [[documentation]] here...
16 Some [[documentation]] here...
17 wiki_content_versions_002:
17 wiki_content_versions_002:
18 updated_on: 2007-03-07 00:08:34 +01:00
18 updated_on: 2007-03-07 00:08:34 +01:00
19 page_id: 1
19 page_id: 1
20 id: 2
20 id: 2
21 version: 2
21 version: 2
22 author_id: 1
22 author_id: 1
23 comments: Small update
23 comments: Small update
24 wiki_content_id: 1
24 wiki_content_id: 1
25 compression: ""
25 compression: ""
26 data: |-
26 data: |-
27 h1. CookBook documentation
27 h1. CookBook documentation
28
28
29
29
30
30
31 Some updated [[documentation]] here...
31 Some updated [[documentation]] here...
32 wiki_content_versions_003:
32 wiki_content_versions_003:
33 updated_on: 2007-03-07 00:10:51 +01:00
33 updated_on: 2007-03-07 00:10:51 +01:00
34 page_id: 1
34 page_id: 1
35 id: 3
35 id: 3
36 version: 3
36 version: 3
37 author_id: 1
37 author_id: 1
38 comments: ""
38 comments: ""
39 wiki_content_id: 1
39 wiki_content_id: 1
40 compression: ""
40 compression: ""
41 data: |-
41 data: |-
42 h1. CookBook documentation
42 h1. CookBook documentation
43 Some updated [[documentation]] here...
43 Some updated [[documentation]] here...
44 wiki_content_versions_004:
44 wiki_content_versions_004:
45 data: |-
45 data: |-
46 h1. Another page
46 h1. Another page
47
47
48 This is a link to a ticket: #2
48 This is a link to a ticket: #2
49 updated_on: 2007-03-08 00:18:07 +01:00
49 updated_on: 2007-03-08 00:18:07 +01:00
50 page_id: 2
50 page_id: 2
51 wiki_content_id: 2
51 wiki_content_id: 2
52 id: 4
52 id: 4
53 version: 1
53 version: 1
54 author_id: 1
54 author_id: 1
55 comments:
55 comments:
56 wiki_content_versions_005:
56 wiki_content_versions_005:
57 data: |-
57 data: |-
58 h1. Title
58 h1. Title
59
59
60 Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Maecenas sed libero.
60 Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Maecenas sed libero.
61
61
62 h2. Heading 1
62 h2. Heading 1
63
63
64 @WHATEVER@
64 @WHATEVER@
65
65
66 Maecenas sed elit sit amet mi accumsan vestibulum non nec velit. Proin porta tincidunt lorem, consequat rhoncus dolor fermentum in.
66 Maecenas sed elit sit amet mi accumsan vestibulum non nec velit. Proin porta tincidunt lorem, consequat rhoncus dolor fermentum in.
67
68 Cras ipsum felis, ultrices at porttitor vel, faucibus eu nunc.
67
69
68 h2. Heading 2
70 h2. Heading 2
69
71
70 Morbi facilisis accumsan orci non pharetra.
72 Morbi facilisis accumsan orci non pharetra.
71 updated_on: 2007-03-08 00:16:07 +01:00
73 updated_on: 2007-03-08 00:16:07 +01:00
72 page_id: 11
74 page_id: 11
73 wiki_content_id: 11
75 wiki_content_id: 11
74 id: 5
76 id: 5
75 version: 2
77 version: 2
76 author_id: 1
78 author_id: 1
77 comments:
79 comments:
80 wiki_content_versions_006:
81 data: |-
82 h1. Title
83
84 Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Maecenas sed libero.
85
86 h2. Heading 1
87
88 @WHATEVER@
89
90 Maecenas sed elit sit amet mi accumsan vestibulum non nec velit. Proin porta tincidunt lorem, consequat rhoncus dolor fermentum in.
91
92 h2. Heading 2
93
94 Morbi facilisis accumsan orci non pharetra.
95 updated_on: 2007-03-08 00:18:07 +01:00
96 page_id: 11
97 wiki_content_id: 11
98 id: 6
99 version: 3
100 author_id: 1
101 comments:
78
102
@@ -1,88 +1,95
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
19
20 class WikiContentTest < ActiveSupport::TestCase
20 class WikiContentTest < ActiveSupport::TestCase
21 fixtures :wikis, :wiki_pages, :wiki_contents, :wiki_content_versions, :users
21 fixtures :wikis, :wiki_pages, :wiki_contents, :wiki_content_versions, :users
22
22
23 def setup
23 def setup
24 @wiki = Wiki.find(1)
24 @wiki = Wiki.find(1)
25 @page = @wiki.pages.first
25 @page = @wiki.pages.first
26 end
26 end
27
27
28 def test_create
28 def test_create
29 page = WikiPage.new(:wiki => @wiki, :title => "Page")
29 page = WikiPage.new(:wiki => @wiki, :title => "Page")
30 page.content = WikiContent.new(:text => "Content text", :author => User.find(1), :comments => "My comment")
30 page.content = WikiContent.new(:text => "Content text", :author => User.find(1), :comments => "My comment")
31 assert page.save
31 assert page.save
32 page.reload
32 page.reload
33
33
34 content = page.content
34 content = page.content
35 assert_kind_of WikiContent, content
35 assert_kind_of WikiContent, content
36 assert_equal 1, content.version
36 assert_equal 1, content.version
37 assert_equal 1, content.versions.length
37 assert_equal 1, content.versions.length
38 assert_equal "Content text", content.text
38 assert_equal "Content text", content.text
39 assert_equal "My comment", content.comments
39 assert_equal "My comment", content.comments
40 assert_equal User.find(1), content.author
40 assert_equal User.find(1), content.author
41 assert_equal content.text, content.versions.last.text
41 assert_equal content.text, content.versions.last.text
42 end
42 end
43
43
44 def test_create_should_send_email_notification
44 def test_create_should_send_email_notification
45 Setting.notified_events = ['wiki_content_added']
45 Setting.notified_events = ['wiki_content_added']
46 ActionMailer::Base.deliveries.clear
46 ActionMailer::Base.deliveries.clear
47 page = WikiPage.new(:wiki => @wiki, :title => "A new page")
47 page = WikiPage.new(:wiki => @wiki, :title => "A new page")
48 page.content = WikiContent.new(:text => "Content text", :author => User.find(1), :comments => "My comment")
48 page.content = WikiContent.new(:text => "Content text", :author => User.find(1), :comments => "My comment")
49 assert page.save
49 assert page.save
50
50
51 assert_equal 1, ActionMailer::Base.deliveries.size
51 assert_equal 1, ActionMailer::Base.deliveries.size
52 end
52 end
53
53
54 def test_update
54 def test_update
55 content = @page.content
55 content = @page.content
56 version_count = content.version
56 version_count = content.version
57 content.text = "My new content"
57 content.text = "My new content"
58 assert content.save
58 assert content.save
59 content.reload
59 content.reload
60 assert_equal version_count+1, content.version
60 assert_equal version_count+1, content.version
61 assert_equal version_count+1, content.versions.length
61 assert_equal version_count+1, content.versions.length
62 end
62 end
63
63
64 def test_update_should_send_email_notification
64 def test_update_should_send_email_notification
65 Setting.notified_events = ['wiki_content_updated']
65 Setting.notified_events = ['wiki_content_updated']
66 ActionMailer::Base.deliveries.clear
66 ActionMailer::Base.deliveries.clear
67 content = @page.content
67 content = @page.content
68 content.text = "My new content"
68 content.text = "My new content"
69 assert content.save
69 assert content.save
70
70
71 assert_equal 1, ActionMailer::Base.deliveries.size
71 assert_equal 1, ActionMailer::Base.deliveries.size
72 end
72 end
73
73
74 def test_fetch_history
74 def test_fetch_history
75 assert !@page.content.versions.empty?
75 assert !@page.content.versions.empty?
76 @page.content.versions.each do |version|
76 @page.content.versions.each do |version|
77 assert_kind_of String, version.text
77 assert_kind_of String, version.text
78 end
78 end
79 end
79 end
80
80
81 def test_large_text_should_not_be_truncated_to_64k
81 def test_large_text_should_not_be_truncated_to_64k
82 page = WikiPage.new(:wiki => @wiki, :title => "Big page")
82 page = WikiPage.new(:wiki => @wiki, :title => "Big page")
83 page.content = WikiContent.new(:text => "a" * 500.kilobyte, :author => User.find(1))
83 page.content = WikiContent.new(:text => "a" * 500.kilobyte, :author => User.find(1))
84 assert page.save
84 assert page.save
85 page.reload
85 page.reload
86 assert_equal 500.kilobyte, page.content.text.size
86 assert_equal 500.kilobyte, page.content.text.size
87 end
87 end
88
89 def test_current_version
90 content = WikiContent.find(11)
91 assert_equal true, content.current_version?
92 assert_equal true, content.versions.first(:order => 'version DESC').current_version?
93 assert_equal false, content.versions.first(:order => 'version ASC').current_version?
94 end
88 end
95 end
General Comments 0
You need to be logged in to leave comments. Login now