Changesets can be listed by changeset number.
The Git repository is here.
- Revision:
- 10
- Log:
Checking in HEAD from RForum's SVN of 22-Jul-2006, 8pm (revision 906).
- Author:
- adh
- Date:
- Sat Jul 22 20:02:44 +0100 2006
- Size:
- 14874 Bytes
- Properties:
- Property svn:executable is set
1 | #!/bin/env ruby |
2 | |
3 | require File.dirname(__FILE__) + '/../test_helper' |
4 | require 'rexml/document' |
5 | require 'topic_controller' |
6 | |
7 | # Raise errors beyond the default web-based presentation |
8 | class TopicController; def rescue_action(e) raise e end; end |
9 | |
10 | class TopicControllerTest < Test::Unit::TestCase |
11 | |
12 | def setup |
13 | setup_controller_test |
14 | setup_forum_fixture |
15 | end |
16 | |
17 | def test_show |
18 | db.execute 'DELETE FROM topic_reads' |
19 | |
20 | r = time { process('show', {'id' => '2'}, {:user_id => 1}) } |
21 | |
22 | assert_success |
23 | |
24 | topic2 = Topic.find(2) |
25 | assert_equal topic2, r.template_objects['topic'] |
26 | assert_equal topic2.posts_with_user_data, r.template_objects['posts'] |
27 | assert_equal_sysdate User.find(1).last_read_time(topic2) |
28 | |
29 | xml = REXML::Document.new(r.body) |
30 | forum_heading = REXML::XPath.first(xml, '//h1').to_s.gsub(/\s/, '') |
31 | assert forum_heading["<ahref='/forum/1'>AVR</a>>Another"] |
32 | |
33 | # It should have all posts rendered in the right order |
34 | assert_match /root message.*(.*\n)*.*another reply/, r.body |
35 | |
36 | # It should remember the time of the last read in a new TopicRead instance |
37 | assert_equal_sysdate User.find(1).topic_reads.find_all[0].updated_at |
38 | # Second read should not create another TopicRead instance |
39 | r = time { process('show', {'id' => 2}, {:user_id => 1}) } |
40 | topic_reads = User.find(1).topic_reads.find_all(nil, 'updated_at asc') |
41 | assert_equal 1, topic_reads.size |
42 | assert_equal_sysdate topic_reads[0].updated_at |
43 | end |
44 | |
45 | def test_show_without_quoting_format |
46 | r = process('show', 'id' => 2) |
47 | assert !(r.has_template_object?('quoting_format')) |
48 | end |
49 | |
50 | def test_show_with_quoting_format |
51 | # TODO this and previous tests seem to test a non-production functionality (unless |
52 | # we will have different ways to quote a line for whatever reason |
53 | r = process('show', {'id' => 2, 'quoting_format' => 'new'}) |
54 | end |
55 | |
56 | MS_BUG_WORKAROUND = /<input name='dummy'/ |
57 | SELF_ID = /<input name='post\[id\]'/ |
58 | PARENT_ID = /<input name='post\[parent_id\]' .*value='102'/ |
59 | TOPIC_ID = /<input name='post\[topic_id\]' .*value='2'/ |
60 | SUBJECT = /<input name='post\[subject\]' .*value='Re: Reply to root post'/ |
61 | GUEST_NAME_ANON = /<input name='post\[guest_name\]' .*/ |
62 | GUEST_NAME_ALEX = /<input name='post\[guest_name\]' .*value='Alex'/ |
63 | GUEST_EMAIL_ANON = /<input name='post\[guest_email\]' .*/ |
64 | GUEST_EMAIL_ALEX = /<input name='post\[guest_email\]' .*value='alex@someplace.org'/ |
65 | SUBMIT_BUTTON = /<input name='submit'/ |
66 | NEW_ATTACHMENT = /<input name='post\[new_attachment\]'/ |
67 | |
68 | def test_show_reply_form |
69 | r = process('show', {'id' => '2', 'reply_to' => '102'}, {:user_id => 1}) |
70 | check_post_in_form(r) |
71 | assert_matches_all [MS_BUG_WORKAROUND, SELF_ID, NEW_ATTACHMENT, PARENT_ID, SUBJECT, TOPIC_ID, SUBMIT_BUTTON], |
72 | form_inputs(r) |
73 | end |
74 | |
75 | def test_show_reply_form_for_anonymous |
76 | r = process('show', {'id' => '2', 'reply_to' => '102'}, {:user_id => nil}) |
77 | |
78 | assert_matches_all [MS_BUG_WORKAROUND, GUEST_EMAIL_ANON, GUEST_NAME_ANON, SELF_ID, NEW_ATTACHMENT, PARENT_ID, |
79 | SUBJECT, TOPIC_ID, SUBMIT_BUTTON], form_inputs(r) |
80 | end |
81 | |
82 | def test_show_reply_form_for_known_guest_name |
83 | r = process('show', {'id' => '2', 'reply_to' => '102'}, |
84 | {:user_id => nil, :guest_name => 'Alex'}) |
85 | |
86 | assert_matches_all [MS_BUG_WORKAROUND, GUEST_EMAIL_ANON, GUEST_NAME_ALEX, |
87 | SELF_ID, NEW_ATTACHMENT, PARENT_ID, SUBJECT, TOPIC_ID, SUBMIT_BUTTON], |
88 | form_inputs(r) |
89 | end |
90 | |
91 | def test_show_reply_form_for_known_guest_email |
92 | r = process('show', {'id' => '2', 'reply_to' => '102'}, |
93 | {:user_id => nil, :guest_email => 'alex@someplace.org'}) |
94 | |
95 | assert_matches_all [MS_BUG_WORKAROUND, GUEST_EMAIL_ALEX, GUEST_NAME_ANON, SELF_ID, NEW_ATTACHMENT, PARENT_ID, |
96 | SUBJECT, TOPIC_ID, SUBMIT_BUTTON], form_inputs(r) |
97 | end |
98 | |
99 | def test_show_post_reply |
100 | new_post = prototype_params(Post, 'parent_id' => 102, 'topic_id' => 2, 'user_id' => 1) |
101 | |
102 | created_post = get_created_post { |
103 | process('show', {'id' => '2', 'post' => new_post}, {:user_id => 1}) |
104 | } |
105 | |
106 | assert created_post.author.is_a?(User) |
107 | assert_equal 1, created_post.user_id |
108 | end |
109 | |
110 | def test_show_post_reply_guest |
111 | new_post = prototype_params(Post, 'parent_id' => 102, 'topic_id' => 2, 'guest_name' => 'Alex', |
112 | 'guest_email' => 'alex@someplace.org') |
113 | |
114 | $break = true |
115 | created_post = get_created_post { |
116 | process('show', {'id' => '2', 'post' => new_post}, {:user_id => nil}) |
117 | } |
118 | |
119 | assert created_post.author.is_a?(Guest) |
120 | assert_equal 'Alex', created_post.guest_name |
121 | assert_equal 'alex@someplace.org', created_post.guest_email |
122 | assert_nil created_post.user_id |
123 | end |
124 | |
125 | def test_show_post_reply_with_error |
126 | new_post = prototype_params(Post, 'parent_id' => 102, 'topic_id' => 2, 'guest_name' => 'Alex', |
127 | 'text' => '') |
128 | |
129 | r = process('show', {'id' => '2', 'post' => new_post}, {:user_id => nil}) |
130 | |
131 | # must go back to the postform (no redirect, the same page is rendered) |
132 | assert_success |
133 | |
134 | # This bug was fixed in 559 |
135 | assert_equal new_post['parent_id'], r.template_objects['post'].parent_id, |
136 | 'parent_id was not transferred to postform' |
137 | |
138 | # This fails with Rails 0.12.1 because of http://dev.rubyonrails.org/ticket/1155 |
139 | assert_equal :formerror_text_short, r.template_objects['post'].errors['text'].to_sym |
140 | assert_equal 'Alex', r.template_objects['post'].guest_name |
141 | end |
142 | |
143 | def test_show_edit_post_submitted |
144 | edited_post = attributes(Post.find(2)) |
145 | edited_post['text'] = 'Edited post text' |
146 | |
147 | assert_edits_post(2, edited_post) { |
148 | process('show', {'id' => '2', 'post' => edited_post}, {:user_id => 2}) |
149 | } |
150 | end |
151 | |
152 | def test_show_edit_invalid_post_submitted |
153 | post_before = Post.find(2) |
154 | edited_post = attributes(post_before) |
155 | # too short text |
156 | edited_post['text'] = 'aa' |
157 | |
158 | r = process('show', {'id' => 2, 'post' => edited_post}, {:user_id => 2}) |
159 | |
160 | # no redirect, go back to the form |
161 | assert_success |
162 | post_after = Post.find(2) |
163 | assert_equal post_before, post_after, 'Post must not be changed by edit with invalid form' |
164 | assert_invalid_column_on_record 'post', 'text' |
165 | end |
166 | |
167 | def test_show_edit_form |
168 | r = process('show', {'id' => 2, 'edit' => 2}, {:user_id => 2}) |
169 | |
170 | assert_success |
171 | assert_equal Post.find(2), r.template_objects['post'] |
172 | end |
173 | |
174 | def test_show_edit_by_unauthorized_user |
175 | post_before = Post.find(2) |
176 | |
177 | assert_raise(RForum::SecurityError) { process('show', {'id' => 2, 'edit' => 1}) } |
178 | |
179 | post_after = Post.find(2) |
180 | assert_equal post_before, post_after, 'Post must not be changed by unauthorized edit' |
181 | end |
182 | |
183 | def test_new_no_post |
184 | topics_count_before = Topic.count |
185 | posts_count_before = Post.count |
186 | |
187 | process('new', 'forum_id' => '1') |
188 | |
189 | assert_equal Post.new.attributes, @response.template_objects['post'].attributes |
190 | assert_equal topics_count_before, Topic.count |
191 | assert_equal posts_count_before, Post.count |
192 | end |
193 | |
194 | def test_new_valid_post_submitted_by_user |
195 | topics_count_before = Topic.count |
196 | posts_count_before = Post.count |
197 | |
198 | r = process('new', {'forum_id' => '1', 'post' => prototype_params(Post)}, {:user_id => 1}) |
199 | |
200 | assert_redirected_to :controller => 'topic', :action => 'show' |
201 | assert_equal topics_count_before + 1, Topic.count |
202 | assert_equal posts_count_before + 1, Post.count |
203 | |
204 | r.headers['location'].match(/([0-9]+)$/) |
205 | created_post = Post.find($1) |
206 | assert created_post.author.is_a?(User) |
207 | assert_equal 1, created_post.user_id |
208 | end |
209 | |
210 | def test_new_valid_post_submitted_by_guest |
211 | topics_count_before = Topic.count |
212 | posts_count_before = Post.count |
213 | |
214 | r = process('new', {'forum_id' => '1', 'post' => |
215 | prototype_params(Post, 'guest_email' => 'a@b.c', 'guest_name' => 'Alex')}) |
216 | |
217 | assert_redirected_to :controller => 'topic', :action => 'show' |
218 | assert_equal topics_count_before + 1, Topic.count |
219 | assert_equal posts_count_before + 1, Post.count |
220 | |
221 | assert_equal 'Alex', r.session[:guest_name] |
222 | assert_equal 'a@b.c', r.session[:guest_email] |
223 | |
224 | r.headers['location'].match(/([0-9]+)$/) |
225 | created_post = Post.find($1) |
226 | assert created_post.author.is_a?(Guest) |
227 | assert_equal 'Alex', created_post.author.guest_name |
228 | assert_equal 'a@b.c', created_post.author.guest_email |
229 | end |
230 | |
231 | def test_new_invalid_post_submitted |
232 | topics_count_before = Topic.count |
233 | posts_count_before = Post.count |
234 | |
235 | # Submit with too short subject |
236 | process('new', 'forum_id' => '1', 'post' => |
237 | prototype_params(Post, {'subject' => '', 'guest_name' => 'Alex'})) |
238 | |
239 | assert_success |
240 | assert_rendered_file 'topic/new' # i.e., no redirection, we are back to the same form |
241 | assert_equal topics_count_before, Topic.count |
242 | assert_equal posts_count_before, Post.count |
243 | assert_equal 'Alex', @response.template_objects['post'].guest_name |
244 | assert @response.template_objects['post'].errors['subject'] |
245 | end |
246 | |
247 | def test_new_fake_user_id |
248 | process('new', {'forum_id' => '1', 'post' => |
249 | prototype_params(Post, {'user_id' => 1})}, {:user_id => nil}) |
250 | assert_redirected_to :controller => 'topic', :action => 'show' |
251 | # verify that user_id of newly created post is nil |
252 | assert_equal nil, Topic.find(@response.redirected_to[:id]).posts.first.user_id |
253 | end |
254 | |
255 | def test_new_author_host |
256 | process('new', {'forum_id' => '1', 'post' => prototype_params(Post)}) |
257 | assert_redirected_to :controller => 'topic', :action => 'show' |
258 | # TODO: remote_ip doesn't work in testing environment |
259 | #assert_equal '127.0.0.1', Topic.find(@response.redirected_to[:id]).posts.first.author_host |
260 | end |
261 | |
262 | def test_new_non_existent_forum |
263 | process('new', 'forum_id' => '-1') |
264 | assert_success |
265 | end |
266 | |
267 | def test_move_successful |
268 | process('move', {'id' => '1', 'to' => '2'}, {:user_id => '1'}) |
269 | assert_redirected_to :action => 'show', :id => 1 |
270 | assert_equal 2, Topic.find(1).forum_id |
271 | end |
272 | |
273 | def test_move_invalid_forum |
274 | assert_raise(ActiveRecord::RecordNotFound) { |
275 | process('move', {'id' => '1', 'to' => '999'}, {:user_id => '1'}) |
276 | } |
277 | end |
278 | |
279 | def test_move_unauthorized |
280 | assert_raise(RForum::SecurityError) { |
281 | process('move', {'id' => '1', 'to' => '2'}, {:user_id => nil}) |
282 | } |
283 | end |
284 | |
285 | def test_delete_post |
286 | process('delete_post', {'id' => '102'}, {:user_id => '1'}) |
287 | assert_redirected_to :controller => 'topic', :action => 'show', :id => 2 |
288 | assert Post.find(102).hidden? |
289 | assert !Post.find(103).hidden? |
290 | end |
291 | |
292 | def test_delete_post_recursive |
293 | process('delete_post', {'id' => '102', 'recursive' => '1'}, {:user_id => '1'}) |
294 | assert_redirected_to :controller => 'topic', :action => 'show', :id => 2 |
295 | assert Post.find(102).hidden? |
296 | assert Post.find(103).hidden? |
297 | end |
298 | |
299 | def test_undelete_post |
300 | Post.find(102).hide(:recursive) |
301 | process('undelete_post', {'id' => '102'}, {:user_id => '1'}) |
302 | assert !Post.find(102).hidden? |
303 | assert Post.find(103).hidden? |
304 | end |
305 | |
306 | def test_undelete_post_recursive |
307 | Post.find(102).hide(:recursive) |
308 | process('undelete_post', {'id' => '102', 'recursive' => '1'}, {:user_id => '1'}) |
309 | assert !Post.find(102).hidden? |
310 | assert !Post.find(103).hidden? |
311 | end |
312 | |
313 | def test_delete_post_unauthorized |
314 | assert_raise(RForum::SecurityError) { |
315 | process('delete_post', {'id' => '102'}, {:user_id => nil}) |
316 | } |
317 | end |
318 | |
319 | def test_delete_post_nonexistant |
320 | assert_raise(ActiveRecord::RecordNotFound) { |
321 | process('delete_post', {'id' => '199'}, {:user_id => 1}) |
322 | } |
323 | end |
324 | |
325 | def test_delete_full_topic |
326 | process('delete_post', {'id' => '1'}, {:user_id => 1}) |
327 | |
328 | assert Topic.find(1).hidden? |
329 | assert Post.find(1).hidden? |
330 | end |
331 | |
332 | def test_show_admin_may_or_maynot_see_deleted_topics |
333 | Topic.find(1).hide |
334 | |
335 | if User.find(1).can_view_deleted_posts?(Topic.find(1)) |
336 | r = process('show', {'id' => 1}, {:user_id => 1}) |
337 | assert_success |
338 | post_ids = r.template_objects['posts'].collect { |p| p.id } |
339 | assert_equal (1..11).to_a, post_ids |
340 | else |
341 | assert_raise(RForum::SecurityError) { process('show', {'id' => 1}, {:user_id => 1}) } |
342 | end |
343 | end |
344 | |
345 | def test_show_user_cannot_see_deleted_topics |
346 | Topic.find(2).hide |
347 | |
348 | assert_raise(RForum::SecurityError) { |
349 | process('show', {'id' => 2}, {:user_id => 2}) |
350 | } |
351 | end |
352 | |
353 | def test_show_guest_cannot_see_deleted_topics |
354 | Topic.find(2).hide |
355 | |
356 | assert_raise(RForum::SecurityError) { |
357 | process('show', {'id' => 2}, {:user_id => nil}) |
358 | } |
359 | end |
360 | |
361 | def test_subscribe_unsubscribe |
362 | topic = Topic.find(1) |
363 | user = User.find(1) |
364 | process('subscribe', {'id' => topic.id}, {:user_id => user.id}) |
365 | assert_redirected_to(:controller => 'topic', :action => 'show', :id => topic.id) |
366 | assert topic.subscribed_by?(user) |
367 | |
368 | process('unsubscribe', {'id' => topic.id}, {:user_id => user.id}) |
369 | assert_redirected_to(:controller => 'topic', :action => 'show', :id => topic.id) |
370 | assert !topic.subscribed_by?(user) |
371 | end |
372 | |
373 | # HELPER METHODS |
374 | |
375 | def form_inputs(response) |
376 | xml = REXML::Document.new(response.body) |
377 | REXML::XPath.match(xml, '//form[@action="/topic/2#postform"]//input').collect {|i| i.to_s}.sort |
378 | end |
379 | |
380 | def check_post_in_form(response) |
381 | post_in_form = response.template_objects['post'] |
382 | assert post_in_form |
383 | assert post_in_form.is_a?(Post) |
384 | assert post_in_form.new_record? |
385 | assert_equal 102, post_in_form.parent_id |
386 | end |
387 | |
388 | def get_created_post |
389 | topic2 = Topic.find(2) |
390 | posts_before = topic2.posts.collect {|p| p.id} |
391 | |
392 | r = yield |
393 | |
394 | posts_after = topic2.posts(true).collect {|p| p.id} |
395 | new_posts = (posts_after - posts_before) |
396 | assert_equal 1, new_posts.size |
397 | new_post = Post.find(new_posts[0]) |
398 | end |
399 | |
400 | def assert_creates_post(expected_post_attributes) |
401 | new_post = get_created_post { yield } |
402 | |
403 | expected_attrs = expected_post_attributes.without('l', 'r') |
404 | assert_attributes_equal(expected_attrs, new_post) |
405 | |
406 | assert_redirected_to(:controller => 'topic', :action => 'show', :id => new_post.topic_id, |
407 | :anchor => new_post.id) |
408 | end |
409 | |
410 | def assert_edits_post(post_id, expected_post_attributes, &proc) |
411 | topic2 = Topic.find(2) |
412 | posts_before = topic2.posts_count |
413 | |
414 | r = time { proc.call } |
415 | |
416 | posts_after = topic2.posts_count |
417 | assert_equal posts_before.size, posts_after.size |
418 | |
419 | edited_post = Post.find(post_id) |
420 | |
421 | expected_post_attributes.delete('updated_at') |
422 | expected_post_attributes.delete('formatted_text') |
423 | assert_attributes_equal(expected_post_attributes, edited_post) |
424 | assert_equal_sysdate edited_post.updated_at |
425 | |
426 | assert_redirected_to(:controller => 'topic', :action => 'show', :id => edited_post.topic_id, |
427 | :anchor => edited_post.id) |
428 | end |
429 | |
430 | def assert_matches_all(a, b) |
431 | a.each_with_index do |exp, i| |
432 | assert_match exp, b[i] |
433 | end |
434 | end |
435 | end |