##// END OF EJS Templates
Merged r12971 (#16255)....
Jean-Philippe Lang -
r12704:c61a6a707f21
parent child
Show More
@@ -1,252 +1,254
1 1 # Redmine - project management software
2 2 # Copyright (C) 2006-2014 Jean-Philippe Lang
3 3 #
4 4 # This program is free software; you can redistribute it and/or
5 5 # modify it under the terms of the GNU General Public License
6 6 # as published by the Free Software Foundation; either version 2
7 7 # of the License, or (at your option) any later version.
8 8 #
9 9 # This program is distributed in the hope that it will be useful,
10 10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 12 # GNU General Public License for more details.
13 13 #
14 14 # You should have received a copy of the GNU General Public License
15 15 # along with this program; if not, write to the Free Software
16 16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17 17
18 18 require 'diff'
19 19 require 'enumerator'
20 20
21 21 class WikiPage < ActiveRecord::Base
22 22 include Redmine::SafeAttributes
23 23
24 24 belongs_to :wiki
25 25 has_one :content, :class_name => 'WikiContent', :foreign_key => 'page_id', :dependent => :destroy
26 26 acts_as_attachable :delete_permission => :delete_wiki_pages_attachments
27 27 acts_as_tree :dependent => :nullify, :order => 'title'
28 28
29 29 acts_as_watchable
30 30 acts_as_event :title => Proc.new {|o| "#{l(:label_wiki)}: #{o.title}"},
31 31 :description => :text,
32 32 :datetime => :created_on,
33 33 :url => Proc.new {|o| {:controller => 'wiki', :action => 'show', :project_id => o.wiki.project, :id => o.title}}
34 34
35 35 acts_as_searchable :columns => ['title', "#{WikiContent.table_name}.text"],
36 36 :include => [{:wiki => :project}, :content],
37 37 :permission => :view_wiki_pages,
38 38 :project_key => "#{Wiki.table_name}.project_id"
39 39
40 40 attr_accessor :redirect_existing_links
41 41
42 42 validates_presence_of :title
43 43 validates_format_of :title, :with => /\A[^,\.\/\?\;\|\s]*\z/
44 44 validates_uniqueness_of :title, :scope => :wiki_id, :case_sensitive => false
45 45 validates_associated :content
46 46
47 47 validate :validate_parent_title
48 48 before_destroy :remove_redirects
49 49 before_save :handle_redirects
50 50
51 51 # eager load information about last updates, without loading text
52 52 scope :with_updated_on, lambda {
53 53 select("#{WikiPage.table_name}.*, #{WikiContent.table_name}.updated_on, #{WikiContent.table_name}.version").
54 54 joins("LEFT JOIN #{WikiContent.table_name} ON #{WikiContent.table_name}.page_id = #{WikiPage.table_name}.id")
55 55 }
56 56
57 57 # Wiki pages that are protected by default
58 58 DEFAULT_PROTECTED_PAGES = %w(sidebar)
59 59
60 60 safe_attributes 'parent_id', 'parent_title',
61 61 :if => lambda {|page, user| page.new_record? || user.allowed_to?(:rename_wiki_pages, page.project)}
62 62
63 63 def initialize(attributes=nil, *args)
64 64 super
65 65 if new_record? && DEFAULT_PROTECTED_PAGES.include?(title.to_s.downcase)
66 66 self.protected = true
67 67 end
68 68 end
69 69
70 70 def visible?(user=User.current)
71 71 !user.nil? && user.allowed_to?(:view_wiki_pages, project)
72 72 end
73 73
74 74 def title=(value)
75 75 value = Wiki.titleize(value)
76 76 @previous_title = read_attribute(:title) if @previous_title.blank?
77 77 write_attribute(:title, value)
78 78 end
79 79
80 80 def handle_redirects
81 81 self.title = Wiki.titleize(title)
82 82 # Manage redirects if the title has changed
83 83 if !@previous_title.blank? && (@previous_title != title) && !new_record?
84 84 # Update redirects that point to the old title
85 85 wiki.redirects.where(:redirects_to => @previous_title).each do |r|
86 86 r.redirects_to = title
87 87 r.title == r.redirects_to ? r.destroy : r.save
88 88 end
89 89 # Remove redirects for the new title
90 90 wiki.redirects.where(:title => title).each(&:destroy)
91 91 # Create a redirect to the new title
92 92 wiki.redirects << WikiRedirect.new(:title => @previous_title, :redirects_to => title) unless redirect_existing_links == "0"
93 93 @previous_title = nil
94 94 end
95 95 end
96 96
97 97 def remove_redirects
98 98 # Remove redirects to this page
99 99 wiki.redirects.where(:redirects_to => title).each(&:destroy)
100 100 end
101 101
102 102 def pretty_title
103 103 WikiPage.pretty_title(title)
104 104 end
105 105
106 106 def content_for_version(version=nil)
107 result = content.versions.find_by_version(version.to_i) if version
108 result ||= content
109 result
107 if content
108 result = content.versions.find_by_version(version.to_i) if version
109 result ||= content
110 result
111 end
110 112 end
111 113
112 114 def diff(version_to=nil, version_from=nil)
113 115 version_to = version_to ? version_to.to_i : self.content.version
114 116 content_to = content.versions.find_by_version(version_to)
115 117 content_from = version_from ? content.versions.find_by_version(version_from.to_i) : content_to.try(:previous)
116 118 return nil unless content_to && content_from
117 119
118 120 if content_from.version > content_to.version
119 121 content_to, content_from = content_from, content_to
120 122 end
121 123
122 124 (content_to && content_from) ? WikiDiff.new(content_to, content_from) : nil
123 125 end
124 126
125 127 def annotate(version=nil)
126 128 version = version ? version.to_i : self.content.version
127 129 c = content.versions.find_by_version(version)
128 130 c ? WikiAnnotate.new(c) : nil
129 131 end
130 132
131 133 def self.pretty_title(str)
132 134 (str && str.is_a?(String)) ? str.tr('_', ' ') : str
133 135 end
134 136
135 137 def project
136 138 wiki.project
137 139 end
138 140
139 141 def text
140 142 content.text if content
141 143 end
142 144
143 145 def updated_on
144 146 unless @updated_on
145 147 if time = read_attribute(:updated_on)
146 148 # content updated_on was eager loaded with the page
147 149 begin
148 150 @updated_on = (self.class.default_timezone == :utc ? Time.parse(time.to_s).utc : Time.parse(time.to_s).localtime)
149 151 rescue
150 152 end
151 153 else
152 154 @updated_on = content && content.updated_on
153 155 end
154 156 end
155 157 @updated_on
156 158 end
157 159
158 160 # Returns true if usr is allowed to edit the page, otherwise false
159 161 def editable_by?(usr)
160 162 !protected? || usr.allowed_to?(:protect_wiki_pages, wiki.project)
161 163 end
162 164
163 165 def attachments_deletable?(usr=User.current)
164 166 editable_by?(usr) && super(usr)
165 167 end
166 168
167 169 def parent_title
168 170 @parent_title || (self.parent && self.parent.pretty_title)
169 171 end
170 172
171 173 def parent_title=(t)
172 174 @parent_title = t
173 175 parent_page = t.blank? ? nil : self.wiki.find_page(t)
174 176 self.parent = parent_page
175 177 end
176 178
177 179 # Saves the page and its content if text was changed
178 180 def save_with_content(content)
179 181 ret = nil
180 182 transaction do
181 183 self.content = content
182 184 if new_record?
183 185 # Rails automatically saves associated content
184 186 ret = save
185 187 else
186 188 ret = save && (content.text_changed? ? content.save : true)
187 189 end
188 190 raise ActiveRecord::Rollback unless ret
189 191 end
190 192 ret
191 193 end
192 194
193 195 protected
194 196
195 197 def validate_parent_title
196 198 errors.add(:parent_title, :invalid) if !@parent_title.blank? && parent.nil?
197 199 errors.add(:parent_title, :circular_dependency) if parent && (parent == self || parent.ancestors.include?(self))
198 200 errors.add(:parent_title, :not_same_project) if parent && (parent.wiki_id != wiki_id)
199 201 end
200 202 end
201 203
202 204 class WikiDiff < Redmine::Helpers::Diff
203 205 attr_reader :content_to, :content_from
204 206
205 207 def initialize(content_to, content_from)
206 208 @content_to = content_to
207 209 @content_from = content_from
208 210 super(content_to.text, content_from.text)
209 211 end
210 212 end
211 213
212 214 class WikiAnnotate
213 215 attr_reader :lines, :content
214 216
215 217 def initialize(content)
216 218 @content = content
217 219 current = content
218 220 current_lines = current.text.split(/\r?\n/)
219 221 @lines = current_lines.collect {|t| [nil, nil, t]}
220 222 positions = []
221 223 current_lines.size.times {|i| positions << i}
222 224 while (current.previous)
223 225 d = current.previous.text.split(/\r?\n/).diff(current.text.split(/\r?\n/)).diffs.flatten
224 226 d.each_slice(3) do |s|
225 227 sign, line = s[0], s[1]
226 228 if sign == '+' && positions[line] && positions[line] != -1
227 229 if @lines[positions[line]][0].nil?
228 230 @lines[positions[line]][0] = current.version
229 231 @lines[positions[line]][1] = current.author
230 232 end
231 233 end
232 234 end
233 235 d.each_slice(3) do |s|
234 236 sign, line = s[0], s[1]
235 237 if sign == '-'
236 238 positions.insert(line, -1)
237 239 else
238 240 positions[line] = nil
239 241 end
240 242 end
241 243 positions.compact!
242 244 # Stop if every line is annotated
243 245 break unless @lines.detect { |line| line[0].nil? }
244 246 current = current.previous
245 247 end
246 248 @lines.each { |line|
247 249 line[0] ||= current.version
248 250 # if the last known version is > 1 (eg. history was cleared), we don't know the author
249 251 line[1] ||= current.author if current.version == 1
250 252 }
251 253 end
252 254 end
@@ -1,959 +1,964
1 1 # Redmine - project management software
2 2 # Copyright (C) 2006-2014 Jean-Philippe Lang
3 3 #
4 4 # This program is free software; you can redistribute it and/or
5 5 # modify it under the terms of the GNU General Public License
6 6 # as published by the Free Software Foundation; either version 2
7 7 # of the License, or (at your option) any later version.
8 8 #
9 9 # This program is distributed in the hope that it will be useful,
10 10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 12 # GNU General Public License for more details.
13 13 #
14 14 # You should have received a copy of the GNU General Public License
15 15 # along with this program; if not, write to the Free Software
16 16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17 17
18 18 require File.expand_path('../../test_helper', __FILE__)
19 19
20 20 class WikiControllerTest < ActionController::TestCase
21 21 fixtures :projects, :users, :roles, :members, :member_roles,
22 22 :enabled_modules, :wikis, :wiki_pages, :wiki_contents,
23 23 :wiki_content_versions, :attachments
24 24
25 25 def setup
26 26 User.current = nil
27 27 end
28 28
29 29 def test_show_start_page
30 30 get :show, :project_id => 'ecookbook'
31 31 assert_response :success
32 32 assert_template 'show'
33 33 assert_tag :tag => 'h1', :content => /CookBook documentation/
34 34
35 35 # child_pages macro
36 36 assert_tag :ul, :attributes => { :class => 'pages-hierarchy' },
37 37 :child => { :tag => 'li',
38 38 :child => { :tag => 'a', :attributes => { :href => '/projects/ecookbook/wiki/Page_with_an_inline_image' },
39 39 :content => 'Page with an inline image' } }
40 40 end
41 41
42 42 def test_export_link
43 43 Role.anonymous.add_permission! :export_wiki_pages
44 44 get :show, :project_id => 'ecookbook'
45 45 assert_response :success
46 46 assert_tag 'a', :attributes => {:href => '/projects/ecookbook/wiki/CookBook_documentation.txt'}
47 47 end
48 48
49 49 def test_show_page_with_name
50 50 get :show, :project_id => 1, :id => 'Another_page'
51 51 assert_response :success
52 52 assert_template 'show'
53 53 assert_tag :tag => 'h1', :content => /Another page/
54 54 # Included page with an inline image
55 55 assert_tag :tag => 'p', :content => /This is an inline image/
56 56 assert_tag :tag => 'img', :attributes => { :src => '/attachments/download/3/logo.gif',
57 57 :alt => 'This is a logo' }
58 58 end
59 59
60 60 def test_show_old_version
61 61 get :show, :project_id => 'ecookbook', :id => 'CookBook_documentation', :version => '2'
62 62 assert_response :success
63 63 assert_template 'show'
64 64
65 65 assert_select 'a[href=?]', '/projects/ecookbook/wiki/CookBook_documentation/1', :text => /Previous/
66 66 assert_select 'a[href=?]', '/projects/ecookbook/wiki/CookBook_documentation/2/diff', :text => /diff/
67 67 assert_select 'a[href=?]', '/projects/ecookbook/wiki/CookBook_documentation/3', :text => /Next/
68 68 assert_select 'a[href=?]', '/projects/ecookbook/wiki/CookBook_documentation', :text => /Current version/
69 69 end
70 70
71 71 def test_show_old_version_with_attachments
72 72 page = WikiPage.find(4)
73 73 assert page.attachments.any?
74 74 content = page.content
75 75 content.text = "update"
76 76 content.save!
77 77
78 78 get :show, :project_id => 'ecookbook', :id => page.title, :version => '1'
79 79 assert_kind_of WikiContent::Version, assigns(:content)
80 80 assert_response :success
81 81 assert_template 'show'
82 82 end
83 83
84 84 def test_show_old_version_without_permission_should_be_denied
85 85 Role.anonymous.remove_permission! :view_wiki_edits
86 86
87 87 get :show, :project_id => 'ecookbook', :id => 'CookBook_documentation', :version => '2'
88 88 assert_redirected_to '/login?back_url=http%3A%2F%2Ftest.host%2Fprojects%2Fecookbook%2Fwiki%2FCookBook_documentation%2F2'
89 89 end
90 90
91 91 def test_show_first_version
92 92 get :show, :project_id => 'ecookbook', :id => 'CookBook_documentation', :version => '1'
93 93 assert_response :success
94 94 assert_template 'show'
95 95
96 96 assert_select 'a', :text => /Previous/, :count => 0
97 97 assert_select 'a', :text => /diff/, :count => 0
98 98 assert_select 'a[href=?]', '/projects/ecookbook/wiki/CookBook_documentation/2', :text => /Next/
99 99 assert_select 'a[href=?]', '/projects/ecookbook/wiki/CookBook_documentation', :text => /Current version/
100 100 end
101 101
102 102 def test_show_redirected_page
103 103 WikiRedirect.create!(:wiki_id => 1, :title => 'Old_title', :redirects_to => 'Another_page')
104 104
105 105 get :show, :project_id => 'ecookbook', :id => 'Old_title'
106 106 assert_redirected_to '/projects/ecookbook/wiki/Another_page'
107 107 end
108 108
109 109 def test_show_with_sidebar
110 110 page = Project.find(1).wiki.pages.new(:title => 'Sidebar')
111 111 page.content = WikiContent.new(:text => 'Side bar content for test_show_with_sidebar')
112 112 page.save!
113 113
114 114 get :show, :project_id => 1, :id => 'Another_page'
115 115 assert_response :success
116 116 assert_tag :tag => 'div', :attributes => {:id => 'sidebar'},
117 117 :content => /Side bar content for test_show_with_sidebar/
118 118 end
119 119
120 120 def test_show_should_display_section_edit_links
121 121 @request.session[:user_id] = 2
122 122 get :show, :project_id => 1, :id => 'Page with sections'
123 123 assert_no_tag 'a', :attributes => {
124 124 :href => '/projects/ecookbook/wiki/Page_with_sections/edit?section=1'
125 125 }
126 126 assert_tag 'a', :attributes => {
127 127 :href => '/projects/ecookbook/wiki/Page_with_sections/edit?section=2'
128 128 }
129 129 assert_tag 'a', :attributes => {
130 130 :href => '/projects/ecookbook/wiki/Page_with_sections/edit?section=3'
131 131 }
132 132 end
133 133
134 134 def test_show_current_version_should_display_section_edit_links
135 135 @request.session[:user_id] = 2
136 136 get :show, :project_id => 1, :id => 'Page with sections', :version => 3
137 137
138 138 assert_tag 'a', :attributes => {
139 139 :href => '/projects/ecookbook/wiki/Page_with_sections/edit?section=2'
140 140 }
141 141 end
142 142
143 143 def test_show_old_version_should_not_display_section_edit_links
144 144 @request.session[:user_id] = 2
145 145 get :show, :project_id => 1, :id => 'Page with sections', :version => 2
146 146
147 147 assert_no_tag 'a', :attributes => {
148 148 :href => '/projects/ecookbook/wiki/Page_with_sections/edit?section=2'
149 149 }
150 150 end
151 151
152 152 def test_show_unexistent_page_without_edit_right
153 153 get :show, :project_id => 1, :id => 'Unexistent page'
154 154 assert_response 404
155 155 end
156 156
157 157 def test_show_unexistent_page_with_edit_right
158 158 @request.session[:user_id] = 2
159 159 get :show, :project_id => 1, :id => 'Unexistent page'
160 160 assert_response :success
161 161 assert_template 'edit'
162 162 end
163 163
164 def test_show_specific_version_of_an_unexistent_page_without_edit_right
165 get :show, :project_id => 1, :id => 'Unexistent page', :version => 1
166 assert_response 404
167 end
168
164 169 def test_show_unexistent_page_with_parent_should_preselect_parent
165 170 @request.session[:user_id] = 2
166 171 get :show, :project_id => 1, :id => 'Unexistent page', :parent => 'Another_page'
167 172 assert_response :success
168 173 assert_template 'edit'
169 174 assert_tag 'select', :attributes => {:name => 'wiki_page[parent_id]'},
170 175 :child => {:tag => 'option', :attributes => {:value => '2', :selected => 'selected'}}
171 176 end
172 177
173 178 def test_show_should_not_show_history_without_permission
174 179 Role.anonymous.remove_permission! :view_wiki_edits
175 180 get :show, :project_id => 1, :id => 'Page with sections', :version => 2
176 181
177 182 assert_response 302
178 183 end
179 184
180 185 def test_show_page_without_content_should_display_the_edit_form
181 186 @request.session[:user_id] = 2
182 187 WikiPage.create!(:title => 'NoContent', :wiki => Project.find(1).wiki)
183 188
184 189 get :show, :project_id => 1, :id => 'NoContent'
185 190 assert_response :success
186 191 assert_template 'edit'
187 192 assert_select 'textarea[name=?]', 'content[text]'
188 193 end
189 194
190 195 def test_create_page
191 196 @request.session[:user_id] = 2
192 197 assert_difference 'WikiPage.count' do
193 198 assert_difference 'WikiContent.count' do
194 199 put :update, :project_id => 1,
195 200 :id => 'New page',
196 201 :content => {:comments => 'Created the page',
197 202 :text => "h1. New page\n\nThis is a new page",
198 203 :version => 0}
199 204 end
200 205 end
201 206 assert_redirected_to :action => 'show', :project_id => 'ecookbook', :id => 'New_page'
202 207 page = Project.find(1).wiki.find_page('New page')
203 208 assert !page.new_record?
204 209 assert_not_nil page.content
205 210 assert_nil page.parent
206 211 assert_equal 'Created the page', page.content.comments
207 212 end
208 213
209 214 def test_create_page_with_attachments
210 215 @request.session[:user_id] = 2
211 216 assert_difference 'WikiPage.count' do
212 217 assert_difference 'Attachment.count' do
213 218 put :update, :project_id => 1,
214 219 :id => 'New page',
215 220 :content => {:comments => 'Created the page',
216 221 :text => "h1. New page\n\nThis is a new page",
217 222 :version => 0},
218 223 :attachments => {'1' => {'file' => uploaded_test_file('testfile.txt', 'text/plain')}}
219 224 end
220 225 end
221 226 page = Project.find(1).wiki.find_page('New page')
222 227 assert_equal 1, page.attachments.count
223 228 assert_equal 'testfile.txt', page.attachments.first.filename
224 229 end
225 230
226 231 def test_create_page_with_parent
227 232 @request.session[:user_id] = 2
228 233 assert_difference 'WikiPage.count' do
229 234 put :update, :project_id => 1, :id => 'New page',
230 235 :content => {:text => "h1. New page\n\nThis is a new page", :version => 0},
231 236 :wiki_page => {:parent_id => 2}
232 237 end
233 238 page = Project.find(1).wiki.find_page('New page')
234 239 assert_equal WikiPage.find(2), page.parent
235 240 end
236 241
237 242 def test_edit_page
238 243 @request.session[:user_id] = 2
239 244 get :edit, :project_id => 'ecookbook', :id => 'Another_page'
240 245
241 246 assert_response :success
242 247 assert_template 'edit'
243 248
244 249 assert_tag 'textarea',
245 250 :attributes => { :name => 'content[text]' },
246 251 :content => "\n"+WikiPage.find_by_title('Another_page').content.text
247 252 end
248 253
249 254 def test_edit_section
250 255 @request.session[:user_id] = 2
251 256 get :edit, :project_id => 'ecookbook', :id => 'Page_with_sections', :section => 2
252 257
253 258 assert_response :success
254 259 assert_template 'edit'
255 260
256 261 page = WikiPage.find_by_title('Page_with_sections')
257 262 section, hash = Redmine::WikiFormatting::Textile::Formatter.new(page.content.text).get_section(2)
258 263
259 264 assert_tag 'textarea',
260 265 :attributes => { :name => 'content[text]' },
261 266 :content => "\n"+section
262 267 assert_tag 'input',
263 268 :attributes => { :name => 'section', :type => 'hidden', :value => '2' }
264 269 assert_tag 'input',
265 270 :attributes => { :name => 'section_hash', :type => 'hidden', :value => hash }
266 271 end
267 272
268 273 def test_edit_invalid_section_should_respond_with_404
269 274 @request.session[:user_id] = 2
270 275 get :edit, :project_id => 'ecookbook', :id => 'Page_with_sections', :section => 10
271 276
272 277 assert_response 404
273 278 end
274 279
275 280 def test_update_page
276 281 @request.session[:user_id] = 2
277 282 assert_no_difference 'WikiPage.count' do
278 283 assert_no_difference 'WikiContent.count' do
279 284 assert_difference 'WikiContent::Version.count' do
280 285 put :update, :project_id => 1,
281 286 :id => 'Another_page',
282 287 :content => {
283 288 :comments => "my comments",
284 289 :text => "edited",
285 290 :version => 1
286 291 }
287 292 end
288 293 end
289 294 end
290 295 assert_redirected_to '/projects/ecookbook/wiki/Another_page'
291 296
292 297 page = Wiki.find(1).pages.find_by_title('Another_page')
293 298 assert_equal "edited", page.content.text
294 299 assert_equal 2, page.content.version
295 300 assert_equal "my comments", page.content.comments
296 301 end
297 302
298 303 def test_update_page_with_parent
299 304 @request.session[:user_id] = 2
300 305 assert_no_difference 'WikiPage.count' do
301 306 assert_no_difference 'WikiContent.count' do
302 307 assert_difference 'WikiContent::Version.count' do
303 308 put :update, :project_id => 1,
304 309 :id => 'Another_page',
305 310 :content => {
306 311 :comments => "my comments",
307 312 :text => "edited",
308 313 :version => 1
309 314 },
310 315 :wiki_page => {:parent_id => '1'}
311 316 end
312 317 end
313 318 end
314 319 assert_redirected_to '/projects/ecookbook/wiki/Another_page'
315 320
316 321 page = Wiki.find(1).pages.find_by_title('Another_page')
317 322 assert_equal "edited", page.content.text
318 323 assert_equal 2, page.content.version
319 324 assert_equal "my comments", page.content.comments
320 325 assert_equal WikiPage.find(1), page.parent
321 326 end
322 327
323 328 def test_update_page_with_failure
324 329 @request.session[:user_id] = 2
325 330 assert_no_difference 'WikiPage.count' do
326 331 assert_no_difference 'WikiContent.count' do
327 332 assert_no_difference 'WikiContent::Version.count' do
328 333 put :update, :project_id => 1,
329 334 :id => 'Another_page',
330 335 :content => {
331 336 :comments => 'a' * 300, # failure here, comment is too long
332 337 :text => 'edited',
333 338 :version => 1
334 339 }
335 340 end
336 341 end
337 342 end
338 343 assert_response :success
339 344 assert_template 'edit'
340 345
341 346 assert_error_tag :descendant => {:content => /Comment is too long/}
342 347 assert_tag :tag => 'textarea', :attributes => {:id => 'content_text'}, :content => "\nedited"
343 348 assert_tag :tag => 'input', :attributes => {:id => 'content_version', :value => '1'}
344 349 end
345 350
346 351 def test_update_page_with_parent_change_only_should_not_create_content_version
347 352 @request.session[:user_id] = 2
348 353 assert_no_difference 'WikiPage.count' do
349 354 assert_no_difference 'WikiContent.count' do
350 355 assert_no_difference 'WikiContent::Version.count' do
351 356 put :update, :project_id => 1,
352 357 :id => 'Another_page',
353 358 :content => {
354 359 :comments => '',
355 360 :text => Wiki.find(1).find_page('Another_page').content.text,
356 361 :version => 1
357 362 },
358 363 :wiki_page => {:parent_id => '1'}
359 364 end
360 365 end
361 366 end
362 367 page = Wiki.find(1).pages.find_by_title('Another_page')
363 368 assert_equal 1, page.content.version
364 369 assert_equal WikiPage.find(1), page.parent
365 370 end
366 371
367 372 def test_update_page_with_attachments_only_should_not_create_content_version
368 373 @request.session[:user_id] = 2
369 374 assert_no_difference 'WikiPage.count' do
370 375 assert_no_difference 'WikiContent.count' do
371 376 assert_no_difference 'WikiContent::Version.count' do
372 377 assert_difference 'Attachment.count' do
373 378 put :update, :project_id => 1,
374 379 :id => 'Another_page',
375 380 :content => {
376 381 :comments => '',
377 382 :text => Wiki.find(1).find_page('Another_page').content.text,
378 383 :version => 1
379 384 },
380 385 :attachments => {'1' => {'file' => uploaded_test_file('testfile.txt', 'text/plain'), 'description' => 'test file'}}
381 386 end
382 387 end
383 388 end
384 389 end
385 390 page = Wiki.find(1).pages.find_by_title('Another_page')
386 391 assert_equal 1, page.content.version
387 392 end
388 393
389 394 def test_update_stale_page_should_not_raise_an_error
390 395 @request.session[:user_id] = 2
391 396 c = Wiki.find(1).find_page('Another_page').content
392 397 c.text = 'Previous text'
393 398 c.save!
394 399 assert_equal 2, c.version
395 400
396 401 assert_no_difference 'WikiPage.count' do
397 402 assert_no_difference 'WikiContent.count' do
398 403 assert_no_difference 'WikiContent::Version.count' do
399 404 put :update, :project_id => 1,
400 405 :id => 'Another_page',
401 406 :content => {
402 407 :comments => 'My comments',
403 408 :text => 'Text should not be lost',
404 409 :version => 1
405 410 }
406 411 end
407 412 end
408 413 end
409 414 assert_response :success
410 415 assert_template 'edit'
411 416 assert_tag :div,
412 417 :attributes => { :class => /error/ },
413 418 :content => /Data has been updated by another user/
414 419 assert_tag 'textarea',
415 420 :attributes => { :name => 'content[text]' },
416 421 :content => /Text should not be lost/
417 422 assert_tag 'input',
418 423 :attributes => { :name => 'content[comments]', :value => 'My comments' }
419 424
420 425 c.reload
421 426 assert_equal 'Previous text', c.text
422 427 assert_equal 2, c.version
423 428 end
424 429
425 430 def test_update_page_without_content_should_create_content
426 431 @request.session[:user_id] = 2
427 432 page = WikiPage.create!(:title => 'NoContent', :wiki => Project.find(1).wiki)
428 433
429 434 assert_no_difference 'WikiPage.count' do
430 435 assert_difference 'WikiContent.count' do
431 436 put :update, :project_id => 1, :id => 'NoContent', :content => {:text => 'Some content'}
432 437 assert_response 302
433 438 end
434 439 end
435 440 assert_equal 'Some content', page.reload.content.text
436 441 end
437 442
438 443 def test_update_section
439 444 @request.session[:user_id] = 2
440 445 page = WikiPage.find_by_title('Page_with_sections')
441 446 section, hash = Redmine::WikiFormatting::Textile::Formatter.new(page.content.text).get_section(2)
442 447 text = page.content.text
443 448
444 449 assert_no_difference 'WikiPage.count' do
445 450 assert_no_difference 'WikiContent.count' do
446 451 assert_difference 'WikiContent::Version.count' do
447 452 put :update, :project_id => 1, :id => 'Page_with_sections',
448 453 :content => {
449 454 :text => "New section content",
450 455 :version => 3
451 456 },
452 457 :section => 2,
453 458 :section_hash => hash
454 459 end
455 460 end
456 461 end
457 462 assert_redirected_to '/projects/ecookbook/wiki/Page_with_sections#section-2'
458 463 assert_equal Redmine::WikiFormatting::Textile::Formatter.new(text).update_section(2, "New section content"), page.reload.content.text
459 464 end
460 465
461 466 def test_update_section_should_allow_stale_page_update
462 467 @request.session[:user_id] = 2
463 468 page = WikiPage.find_by_title('Page_with_sections')
464 469 section, hash = Redmine::WikiFormatting::Textile::Formatter.new(page.content.text).get_section(2)
465 470 text = page.content.text
466 471
467 472 assert_no_difference 'WikiPage.count' do
468 473 assert_no_difference 'WikiContent.count' do
469 474 assert_difference 'WikiContent::Version.count' do
470 475 put :update, :project_id => 1, :id => 'Page_with_sections',
471 476 :content => {
472 477 :text => "New section content",
473 478 :version => 2 # Current version is 3
474 479 },
475 480 :section => 2,
476 481 :section_hash => hash
477 482 end
478 483 end
479 484 end
480 485 assert_redirected_to '/projects/ecookbook/wiki/Page_with_sections#section-2'
481 486 page.reload
482 487 assert_equal Redmine::WikiFormatting::Textile::Formatter.new(text).update_section(2, "New section content"), page.content.text
483 488 assert_equal 4, page.content.version
484 489 end
485 490
486 491 def test_update_section_should_not_allow_stale_section_update
487 492 @request.session[:user_id] = 2
488 493
489 494 assert_no_difference 'WikiPage.count' do
490 495 assert_no_difference 'WikiContent.count' do
491 496 assert_no_difference 'WikiContent::Version.count' do
492 497 put :update, :project_id => 1, :id => 'Page_with_sections',
493 498 :content => {
494 499 :comments => 'My comments',
495 500 :text => "Text should not be lost",
496 501 :version => 3
497 502 },
498 503 :section => 2,
499 504 :section_hash => Digest::MD5.hexdigest("wrong hash")
500 505 end
501 506 end
502 507 end
503 508 assert_response :success
504 509 assert_template 'edit'
505 510 assert_tag :div,
506 511 :attributes => { :class => /error/ },
507 512 :content => /Data has been updated by another user/
508 513 assert_tag 'textarea',
509 514 :attributes => { :name => 'content[text]' },
510 515 :content => /Text should not be lost/
511 516 assert_tag 'input',
512 517 :attributes => { :name => 'content[comments]', :value => 'My comments' }
513 518 end
514 519
515 520 def test_preview
516 521 @request.session[:user_id] = 2
517 522 xhr :post, :preview, :project_id => 1, :id => 'CookBook_documentation',
518 523 :content => { :comments => '',
519 524 :text => 'this is a *previewed text*',
520 525 :version => 3 }
521 526 assert_response :success
522 527 assert_template 'common/_preview'
523 528 assert_tag :tag => 'strong', :content => /previewed text/
524 529 end
525 530
526 531 def test_preview_new_page
527 532 @request.session[:user_id] = 2
528 533 xhr :post, :preview, :project_id => 1, :id => 'New page',
529 534 :content => { :text => 'h1. New page',
530 535 :comments => '',
531 536 :version => 0 }
532 537 assert_response :success
533 538 assert_template 'common/_preview'
534 539 assert_tag :tag => 'h1', :content => /New page/
535 540 end
536 541
537 542 def test_history
538 543 @request.session[:user_id] = 2
539 544 get :history, :project_id => 'ecookbook', :id => 'CookBook_documentation'
540 545 assert_response :success
541 546 assert_template 'history'
542 547 assert_not_nil assigns(:versions)
543 548 assert_equal 3, assigns(:versions).size
544 549
545 550 assert_select "input[type=submit][name=commit]"
546 551 assert_select 'td' do
547 552 assert_select 'a[href=?]', '/projects/ecookbook/wiki/CookBook_documentation/2', :text => '2'
548 553 assert_select 'a[href=?]', '/projects/ecookbook/wiki/CookBook_documentation/2/annotate', :text => 'Annotate'
549 554 assert_select 'a[href=?]', '/projects/ecookbook/wiki/CookBook_documentation/2', :text => 'Delete'
550 555 end
551 556 end
552 557
553 558 def test_history_with_one_version
554 559 @request.session[:user_id] = 2
555 560 get :history, :project_id => 'ecookbook', :id => 'Another_page'
556 561 assert_response :success
557 562 assert_template 'history'
558 563 assert_not_nil assigns(:versions)
559 564 assert_equal 1, assigns(:versions).size
560 565 assert_select "input[type=submit][name=commit]", false
561 566 assert_select 'td' do
562 567 assert_select 'a[href=?]', '/projects/ecookbook/wiki/Another_page/1', :text => '1'
563 568 assert_select 'a[href=?]', '/projects/ecookbook/wiki/Another_page/1/annotate', :text => 'Annotate'
564 569 assert_select 'a[href=?]', '/projects/ecookbook/wiki/Another_page/1', :text => 'Delete', :count => 0
565 570 end
566 571 end
567 572
568 573 def test_diff
569 574 content = WikiPage.find(1).content
570 575 assert_difference 'WikiContent::Version.count', 2 do
571 576 content.text = "Line removed\nThis is a sample text for testing diffs"
572 577 content.save!
573 578 content.text = "This is a sample text for testing diffs\nLine added"
574 579 content.save!
575 580 end
576 581
577 582 get :diff, :project_id => 1, :id => 'CookBook_documentation', :version => content.version, :version_from => (content.version - 1)
578 583 assert_response :success
579 584 assert_template 'diff'
580 585 assert_select 'span.diff_out', :text => 'Line removed'
581 586 assert_select 'span.diff_in', :text => 'Line added'
582 587 end
583 588
584 589 def test_diff_with_invalid_version_should_respond_with_404
585 590 get :diff, :project_id => 1, :id => 'CookBook_documentation', :version => '99'
586 591 assert_response 404
587 592 end
588 593
589 594 def test_diff_with_invalid_version_from_should_respond_with_404
590 595 get :diff, :project_id => 1, :id => 'CookBook_documentation', :version => '99', :version_from => '98'
591 596 assert_response 404
592 597 end
593 598
594 599 def test_annotate
595 600 get :annotate, :project_id => 1, :id => 'CookBook_documentation', :version => 2
596 601 assert_response :success
597 602 assert_template 'annotate'
598 603
599 604 # Line 1
600 605 assert_tag :tag => 'tr', :child => {
601 606 :tag => 'th', :attributes => {:class => 'line-num'}, :content => '1', :sibling => {
602 607 :tag => 'td', :attributes => {:class => 'author'}, :content => /John Smith/, :sibling => {
603 608 :tag => 'td', :content => /h1\. CookBook documentation/
604 609 }
605 610 }
606 611 }
607 612
608 613 # Line 5
609 614 assert_tag :tag => 'tr', :child => {
610 615 :tag => 'th', :attributes => {:class => 'line-num'}, :content => '5', :sibling => {
611 616 :tag => 'td', :attributes => {:class => 'author'}, :content => /Redmine Admin/, :sibling => {
612 617 :tag => 'td', :content => /Some updated \[\[documentation\]\] here/
613 618 }
614 619 }
615 620 }
616 621 end
617 622
618 623 def test_annotate_with_invalid_version_should_respond_with_404
619 624 get :annotate, :project_id => 1, :id => 'CookBook_documentation', :version => '99'
620 625 assert_response 404
621 626 end
622 627
623 628 def test_get_rename
624 629 @request.session[:user_id] = 2
625 630 get :rename, :project_id => 1, :id => 'Another_page'
626 631 assert_response :success
627 632 assert_template 'rename'
628 633 assert_tag 'option',
629 634 :attributes => {:value => ''},
630 635 :content => '',
631 636 :parent => {:tag => 'select', :attributes => {:name => 'wiki_page[parent_id]'}}
632 637 assert_no_tag 'option',
633 638 :attributes => {:selected => 'selected'},
634 639 :parent => {:tag => 'select', :attributes => {:name => 'wiki_page[parent_id]'}}
635 640 end
636 641
637 642 def test_get_rename_child_page
638 643 @request.session[:user_id] = 2
639 644 get :rename, :project_id => 1, :id => 'Child_1'
640 645 assert_response :success
641 646 assert_template 'rename'
642 647 assert_tag 'option',
643 648 :attributes => {:value => ''},
644 649 :content => '',
645 650 :parent => {:tag => 'select', :attributes => {:name => 'wiki_page[parent_id]'}}
646 651 assert_tag 'option',
647 652 :attributes => {:value => '2', :selected => 'selected'},
648 653 :content => /Another page/,
649 654 :parent => {
650 655 :tag => 'select',
651 656 :attributes => {:name => 'wiki_page[parent_id]'}
652 657 }
653 658 end
654 659
655 660 def test_rename_with_redirect
656 661 @request.session[:user_id] = 2
657 662 post :rename, :project_id => 1, :id => 'Another_page',
658 663 :wiki_page => { :title => 'Another renamed page',
659 664 :redirect_existing_links => 1 }
660 665 assert_redirected_to :action => 'show', :project_id => 'ecookbook', :id => 'Another_renamed_page'
661 666 wiki = Project.find(1).wiki
662 667 # Check redirects
663 668 assert_not_nil wiki.find_page('Another page')
664 669 assert_nil wiki.find_page('Another page', :with_redirect => false)
665 670 end
666 671
667 672 def test_rename_without_redirect
668 673 @request.session[:user_id] = 2
669 674 post :rename, :project_id => 1, :id => 'Another_page',
670 675 :wiki_page => { :title => 'Another renamed page',
671 676 :redirect_existing_links => "0" }
672 677 assert_redirected_to :action => 'show', :project_id => 'ecookbook', :id => 'Another_renamed_page'
673 678 wiki = Project.find(1).wiki
674 679 # Check that there's no redirects
675 680 assert_nil wiki.find_page('Another page')
676 681 end
677 682
678 683 def test_rename_with_parent_assignment
679 684 @request.session[:user_id] = 2
680 685 post :rename, :project_id => 1, :id => 'Another_page',
681 686 :wiki_page => { :title => 'Another page', :redirect_existing_links => "0", :parent_id => '4' }
682 687 assert_redirected_to :action => 'show', :project_id => 'ecookbook', :id => 'Another_page'
683 688 assert_equal WikiPage.find(4), WikiPage.find_by_title('Another_page').parent
684 689 end
685 690
686 691 def test_rename_with_parent_unassignment
687 692 @request.session[:user_id] = 2
688 693 post :rename, :project_id => 1, :id => 'Child_1',
689 694 :wiki_page => { :title => 'Child 1', :redirect_existing_links => "0", :parent_id => '' }
690 695 assert_redirected_to :action => 'show', :project_id => 'ecookbook', :id => 'Child_1'
691 696 assert_nil WikiPage.find_by_title('Child_1').parent
692 697 end
693 698
694 699 def test_destroy_a_page_without_children_should_not_ask_confirmation
695 700 @request.session[:user_id] = 2
696 701 delete :destroy, :project_id => 1, :id => 'Child_2'
697 702 assert_redirected_to :action => 'index', :project_id => 'ecookbook'
698 703 end
699 704
700 705 def test_destroy_parent_should_ask_confirmation
701 706 @request.session[:user_id] = 2
702 707 assert_no_difference('WikiPage.count') do
703 708 delete :destroy, :project_id => 1, :id => 'Another_page'
704 709 end
705 710 assert_response :success
706 711 assert_template 'destroy'
707 712 assert_select 'form' do
708 713 assert_select 'input[name=todo][value=nullify]'
709 714 assert_select 'input[name=todo][value=destroy]'
710 715 assert_select 'input[name=todo][value=reassign]'
711 716 end
712 717 end
713 718
714 719 def test_destroy_parent_with_nullify_should_delete_parent_only
715 720 @request.session[:user_id] = 2
716 721 assert_difference('WikiPage.count', -1) do
717 722 delete :destroy, :project_id => 1, :id => 'Another_page', :todo => 'nullify'
718 723 end
719 724 assert_redirected_to :action => 'index', :project_id => 'ecookbook'
720 725 assert_nil WikiPage.find_by_id(2)
721 726 end
722 727
723 728 def test_destroy_parent_with_cascade_should_delete_descendants
724 729 @request.session[:user_id] = 2
725 730 assert_difference('WikiPage.count', -4) do
726 731 delete :destroy, :project_id => 1, :id => 'Another_page', :todo => 'destroy'
727 732 end
728 733 assert_redirected_to :action => 'index', :project_id => 'ecookbook'
729 734 assert_nil WikiPage.find_by_id(2)
730 735 assert_nil WikiPage.find_by_id(5)
731 736 end
732 737
733 738 def test_destroy_parent_with_reassign
734 739 @request.session[:user_id] = 2
735 740 assert_difference('WikiPage.count', -1) do
736 741 delete :destroy, :project_id => 1, :id => 'Another_page', :todo => 'reassign', :reassign_to_id => 1
737 742 end
738 743 assert_redirected_to :action => 'index', :project_id => 'ecookbook'
739 744 assert_nil WikiPage.find_by_id(2)
740 745 assert_equal WikiPage.find(1), WikiPage.find_by_id(5).parent
741 746 end
742 747
743 748 def test_destroy_version
744 749 @request.session[:user_id] = 2
745 750 assert_difference 'WikiContent::Version.count', -1 do
746 751 assert_no_difference 'WikiContent.count' do
747 752 assert_no_difference 'WikiPage.count' do
748 753 delete :destroy_version, :project_id => 'ecookbook', :id => 'CookBook_documentation', :version => 2
749 754 assert_redirected_to '/projects/ecookbook/wiki/CookBook_documentation/history'
750 755 end
751 756 end
752 757 end
753 758 end
754 759
755 760 def test_index
756 761 get :index, :project_id => 'ecookbook'
757 762 assert_response :success
758 763 assert_template 'index'
759 764 pages = assigns(:pages)
760 765 assert_not_nil pages
761 766 assert_equal Project.find(1).wiki.pages.size, pages.size
762 767 assert_equal pages.first.content.updated_on, pages.first.updated_on
763 768
764 769 assert_tag :ul, :attributes => { :class => 'pages-hierarchy' },
765 770 :child => { :tag => 'li', :child => { :tag => 'a', :attributes => { :href => '/projects/ecookbook/wiki/CookBook_documentation' },
766 771 :content => 'CookBook documentation' },
767 772 :child => { :tag => 'ul',
768 773 :child => { :tag => 'li',
769 774 :child => { :tag => 'a', :attributes => { :href => '/projects/ecookbook/wiki/Page_with_an_inline_image' },
770 775 :content => 'Page with an inline image' } } } },
771 776 :child => { :tag => 'li', :child => { :tag => 'a', :attributes => { :href => '/projects/ecookbook/wiki/Another_page' },
772 777 :content => 'Another page' } }
773 778 end
774 779
775 780 def test_index_should_include_atom_link
776 781 get :index, :project_id => 'ecookbook'
777 782 assert_tag 'a', :attributes => { :href => '/projects/ecookbook/activity.atom?show_wiki_edits=1'}
778 783 end
779 784
780 785 def test_export_to_html
781 786 @request.session[:user_id] = 2
782 787 get :export, :project_id => 'ecookbook'
783 788
784 789 assert_response :success
785 790 assert_not_nil assigns(:pages)
786 791 assert assigns(:pages).any?
787 792 assert_equal "text/html", @response.content_type
788 793
789 794 assert_select "a[name=?]", "CookBook_documentation"
790 795 assert_select "a[name=?]", "Another_page"
791 796 assert_select "a[name=?]", "Page_with_an_inline_image"
792 797 end
793 798
794 799 def test_export_to_pdf
795 800 @request.session[:user_id] = 2
796 801 get :export, :project_id => 'ecookbook', :format => 'pdf'
797 802
798 803 assert_response :success
799 804 assert_not_nil assigns(:pages)
800 805 assert assigns(:pages).any?
801 806 assert_equal 'application/pdf', @response.content_type
802 807 assert_equal 'attachment; filename="ecookbook.pdf"', @response.headers['Content-Disposition']
803 808 assert @response.body.starts_with?('%PDF')
804 809 end
805 810
806 811 def test_export_without_permission_should_be_denied
807 812 @request.session[:user_id] = 2
808 813 Role.find_by_name('Manager').remove_permission! :export_wiki_pages
809 814 get :export, :project_id => 'ecookbook'
810 815
811 816 assert_response 403
812 817 end
813 818
814 819 def test_date_index
815 820 get :date_index, :project_id => 'ecookbook'
816 821
817 822 assert_response :success
818 823 assert_template 'date_index'
819 824 assert_not_nil assigns(:pages)
820 825 assert_not_nil assigns(:pages_by_date)
821 826
822 827 assert_tag 'a', :attributes => { :href => '/projects/ecookbook/activity.atom?show_wiki_edits=1'}
823 828 end
824 829
825 830 def test_not_found
826 831 get :show, :project_id => 999
827 832 assert_response 404
828 833 end
829 834
830 835 def test_protect_page
831 836 page = WikiPage.find_by_wiki_id_and_title(1, 'Another_page')
832 837 assert !page.protected?
833 838 @request.session[:user_id] = 2
834 839 post :protect, :project_id => 1, :id => page.title, :protected => '1'
835 840 assert_redirected_to :action => 'show', :project_id => 'ecookbook', :id => 'Another_page'
836 841 assert page.reload.protected?
837 842 end
838 843
839 844 def test_unprotect_page
840 845 page = WikiPage.find_by_wiki_id_and_title(1, 'CookBook_documentation')
841 846 assert page.protected?
842 847 @request.session[:user_id] = 2
843 848 post :protect, :project_id => 1, :id => page.title, :protected => '0'
844 849 assert_redirected_to :action => 'show', :project_id => 'ecookbook', :id => 'CookBook_documentation'
845 850 assert !page.reload.protected?
846 851 end
847 852
848 853 def test_show_page_with_edit_link
849 854 @request.session[:user_id] = 2
850 855 get :show, :project_id => 1
851 856 assert_response :success
852 857 assert_template 'show'
853 858 assert_tag :tag => 'a', :attributes => { :href => '/projects/1/wiki/CookBook_documentation/edit' }
854 859 end
855 860
856 861 def test_show_page_without_edit_link
857 862 @request.session[:user_id] = 4
858 863 get :show, :project_id => 1
859 864 assert_response :success
860 865 assert_template 'show'
861 866 assert_no_tag :tag => 'a', :attributes => { :href => '/projects/1/wiki/CookBook_documentation/edit' }
862 867 end
863 868
864 869 def test_show_pdf
865 870 @request.session[:user_id] = 2
866 871 get :show, :project_id => 1, :format => 'pdf'
867 872 assert_response :success
868 873 assert_not_nil assigns(:page)
869 874 assert_equal 'application/pdf', @response.content_type
870 875 assert_equal 'attachment; filename="CookBook_documentation.pdf"',
871 876 @response.headers['Content-Disposition']
872 877 end
873 878
874 879 def test_show_html
875 880 @request.session[:user_id] = 2
876 881 get :show, :project_id => 1, :format => 'html'
877 882 assert_response :success
878 883 assert_not_nil assigns(:page)
879 884 assert_equal 'text/html', @response.content_type
880 885 assert_equal 'attachment; filename="CookBook_documentation.html"',
881 886 @response.headers['Content-Disposition']
882 887 assert_tag 'h1', :content => 'CookBook documentation'
883 888 end
884 889
885 890 def test_show_versioned_html
886 891 @request.session[:user_id] = 2
887 892 get :show, :project_id => 1, :format => 'html', :version => 2
888 893 assert_response :success
889 894 assert_not_nil assigns(:content)
890 895 assert_equal 2, assigns(:content).version
891 896 assert_equal 'text/html', @response.content_type
892 897 assert_equal 'attachment; filename="CookBook_documentation.html"',
893 898 @response.headers['Content-Disposition']
894 899 assert_tag 'h1', :content => 'CookBook documentation'
895 900 end
896 901
897 902 def test_show_txt
898 903 @request.session[:user_id] = 2
899 904 get :show, :project_id => 1, :format => 'txt'
900 905 assert_response :success
901 906 assert_not_nil assigns(:page)
902 907 assert_equal 'text/plain', @response.content_type
903 908 assert_equal 'attachment; filename="CookBook_documentation.txt"',
904 909 @response.headers['Content-Disposition']
905 910 assert_include 'h1. CookBook documentation', @response.body
906 911 end
907 912
908 913 def test_show_versioned_txt
909 914 @request.session[:user_id] = 2
910 915 get :show, :project_id => 1, :format => 'txt', :version => 2
911 916 assert_response :success
912 917 assert_not_nil assigns(:content)
913 918 assert_equal 2, assigns(:content).version
914 919 assert_equal 'text/plain', @response.content_type
915 920 assert_equal 'attachment; filename="CookBook_documentation.txt"',
916 921 @response.headers['Content-Disposition']
917 922 assert_include 'h1. CookBook documentation', @response.body
918 923 end
919 924
920 925 def test_edit_unprotected_page
921 926 # Non members can edit unprotected wiki pages
922 927 @request.session[:user_id] = 4
923 928 get :edit, :project_id => 1, :id => 'Another_page'
924 929 assert_response :success
925 930 assert_template 'edit'
926 931 end
927 932
928 933 def test_edit_protected_page_by_nonmember
929 934 # Non members can't edit protected wiki pages
930 935 @request.session[:user_id] = 4
931 936 get :edit, :project_id => 1, :id => 'CookBook_documentation'
932 937 assert_response 403
933 938 end
934 939
935 940 def test_edit_protected_page_by_member
936 941 @request.session[:user_id] = 2
937 942 get :edit, :project_id => 1, :id => 'CookBook_documentation'
938 943 assert_response :success
939 944 assert_template 'edit'
940 945 end
941 946
942 947 def test_history_of_non_existing_page_should_return_404
943 948 get :history, :project_id => 1, :id => 'Unknown_page'
944 949 assert_response 404
945 950 end
946 951
947 952 def test_add_attachment
948 953 @request.session[:user_id] = 2
949 954 assert_difference 'Attachment.count' do
950 955 post :add_attachment, :project_id => 1, :id => 'CookBook_documentation',
951 956 :attachments => {
952 957 '1' => {'file' => uploaded_test_file('testfile.txt', 'text/plain'),
953 958 'description' => 'test file'}
954 959 }
955 960 end
956 961 attachment = Attachment.order('id DESC').first
957 962 assert_equal Wiki.find(1).find_page('CookBook_documentation'), attachment.container
958 963 end
959 964 end
General Comments 0
You need to be logged in to leave comments. Login now