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