Commit 629998e741fee1c5748c43833a458be38122063e
Committed by
Daniela Feitosa
1 parent
cc6d42c3
Exists in
master
and in
8 other branches
Fixing crash on visualizing forum with comments from unauthenticated users
(ActionItem1822)
Showing
11 changed files
with
104 additions
and
27 deletions
Show diff stats
app/helpers/forum_helper.rb
... | ... | @@ -40,8 +40,12 @@ module ForumHelper |
40 | 40 | end |
41 | 41 | |
42 | 42 | def last_topic_update(article) |
43 | - last_update_at, last_update_by = (article.comments.count.zero? ? [article.updated_at, article.author] : [article.comments.last.created_at, article.comments.last.author]) | |
44 | - time_ago_as_sentence(last_update_at) + ' ' + _('ago') + ' ' + _('by') + ' ' + link_to(last_update_by.name, last_update_by.url) | |
43 | + info = article.info_from_last_update | |
44 | + if info[:author_url] | |
45 | + time_ago_as_sentence(info[:date]) + ' ' + _('ago') + ' ' + _('by') + ' ' + link_to(info[:author_name], info[:author_url]) | |
46 | + else | |
47 | + time_ago_as_sentence(info[:date]) + ' ' + _('ago') + ' ' + _('by') + ' ' + info[:author_name] | |
48 | + end | |
45 | 49 | end |
46 | 50 | |
47 | 51 | end | ... | ... |
app/models/article.rb
... | ... | @@ -232,6 +232,15 @@ class Article < ActiveRecord::Base |
232 | 232 | self.parent and self.parent.blog? |
233 | 233 | end |
234 | 234 | |
235 | + def info_from_last_update | |
236 | + last_comment = comments.last | |
237 | + if last_comment | |
238 | + {:date => last_comment.created_at, :author_name => last_comment.author_name, :author_url => last_comment.author_url} | |
239 | + else | |
240 | + {:date => updated_at, :author_name => author.name, :author_url => author.url} | |
241 | + end | |
242 | + end | |
243 | + | |
235 | 244 | def url |
236 | 245 | @url ||= self.profile.url.merge(:page => path.split('/')) |
237 | 246 | end | ... | ... |
app/models/comment.rb
features/forum.feature
... | ... | @@ -67,3 +67,29 @@ Feature: forum |
67 | 67 | And I go to /joaosilva/forum-one |
68 | 68 | When I follow "Configure forum" |
69 | 69 | Then I should be on edit "Forum One" by joaosilva |
70 | + | |
71 | + Scenario: last topic update by unautenticated user should not link | |
72 | + Given the following forums | |
73 | + | owner | name | | |
74 | + | joaosilva | Forum | | |
75 | + And the following articles | |
76 | + | owner | name | parent | | |
77 | + | joaosilva | Post one | Forum | | |
78 | + And the following comments | |
79 | + | article | name | email | title | body | | |
80 | + | Post one | Joao | joao@example.com | Hi all | Hi all | | |
81 | + When I go to /joaosilva/forum | |
82 | + Then I should not see "Joao" link | |
83 | + | |
84 | + Scenario: last topic update by autenticated user should link to profile url | |
85 | + Given the following forums | |
86 | + | owner | name | | |
87 | + | joaosilva | Forum | | |
88 | + And the following articles | |
89 | + | owner | name | parent | | |
90 | + | joaosilva | Post one | Forum | | |
91 | + And the following comments | |
92 | + | article | author | title | body | | |
93 | + | Post one | joaosilva | Hi all | Hi all | | |
94 | + When I go to /joaosilva/forum | |
95 | + Then I should see "Joao" linking to "http:///joaosilva" | ... | ... |
features/step_definitions/custom_webrat_steps.rb
... | ... | @@ -6,6 +6,11 @@ When /^I should not see "([^\"]+)" link$/ do |text| |
6 | 6 | response.should_not have_selector("a:contains('#{text}')") |
7 | 7 | end |
8 | 8 | |
9 | +When /^I should see "([^\"]+)" linking to "([^\"]+)"$/ do |text, href| | |
10 | + response.should have_selector("a:contains('#{text}')") | |
11 | + response.should have_selector("a[href='#{href}']") | |
12 | +end | |
13 | + | |
9 | 14 | Then /^I should be exactly on (.+)$/ do |page_name| |
10 | 15 | URI.parse(current_url).request_uri.should == path_to(page_name) |
11 | 16 | end | ... | ... |
features/step_definitions/noosfero_steps.rb
... | ... | @@ -52,9 +52,14 @@ Given /^the following (articles|events|blogs|folders|forums|galleries)$/ do |con |
52 | 52 | }[content] || raise("Don't know how to build %s" % content) |
53 | 53 | table.hashes.map{|item| item.dup}.each do |item| |
54 | 54 | owner_identifier = item.delete("owner") |
55 | + parent = item.delete("parent") | |
55 | 56 | owner = Profile[owner_identifier] |
56 | 57 | home = item.delete("homepage") |
57 | - result = klass.create!(item.merge(:profile => owner)) | |
58 | + result = klass.new(item.merge(:profile => owner)) | |
59 | + if parent | |
60 | + result.parent = Article.find_by_name(parent) | |
61 | + end | |
62 | + result.save! | |
58 | 63 | if home |
59 | 64 | owner.home_page = result |
60 | 65 | owner.save! |
... | ... | @@ -318,8 +323,11 @@ Given /^the following comments?$/ do |table| |
318 | 323 | table.hashes.each do |item| |
319 | 324 | data = item.dup |
320 | 325 | article = Article.find_by_name(data.delete("article")) |
321 | - author = Profile[data.delete("author")] | |
322 | - comment = article.comments.build(:author => author, :title => data.delete("title"), :body => data.delete("body")) | |
326 | + author = data.delete("author") | |
327 | + comment = article.comments.build(data) | |
328 | + if author | |
329 | + comment.author = Profile[author] | |
330 | + end | |
323 | 331 | comment.save! |
324 | 332 | end |
325 | 333 | end | ... | ... |
test/test_helper.rb
... | ... | @@ -193,7 +193,8 @@ module NoosferoTestHelper |
193 | 193 | end |
194 | 194 | |
195 | 195 | def content_tag(tag, content, options = {}) |
196 | - "<#{tag}>#{content}</#{tag}>" | |
196 | + tag_attr = options.blank? ? '' : ' ' + options.collect{ |o| "#{o[0]}=\"#{o[1]}\"" }.join(' ') | |
197 | + "<#{tag}#{tag_attr}>#{content}</#{tag}>" | |
197 | 198 | end |
198 | 199 | |
199 | 200 | def submit_tag(content, options = {}) |
... | ... | @@ -228,6 +229,8 @@ module NoosferoTestHelper |
228 | 229 | icon |
229 | 230 | end |
230 | 231 | |
232 | + def will_paginate(arg1, arg2) | |
233 | + end | |
231 | 234 | end |
232 | 235 | |
233 | 236 | class ActionController::IntegrationTest | ... | ... |
test/unit/article_block_test.rb
... | ... | @@ -89,7 +89,7 @@ class ArticleBlockTest < Test::Unit::TestCase |
89 | 89 | block.expects(:title).returns('') |
90 | 90 | block.stubs(:article).returns(article) |
91 | 91 | |
92 | - assert_equal "<h3><span></span></h3>Article content", instance_eval(&block.content) | |
92 | + assert_equal "<h3 class=\"block-title empty\"><span></span></h3>Article content", instance_eval(&block.content) | |
93 | 93 | end |
94 | 94 | |
95 | 95 | should "display title if defined" do |
... | ... | @@ -99,7 +99,7 @@ class ArticleBlockTest < Test::Unit::TestCase |
99 | 99 | block.expects(:title).returns('Article title') |
100 | 100 | block.stubs(:article).returns(article) |
101 | 101 | |
102 | - assert_equal "<h3><span>Article title</span></h3>Article content", instance_eval(&block.content) | |
102 | + assert_equal "<h3 class=\"block-title\"><span>Article title</span></h3>Article content", instance_eval(&block.content) | |
103 | 103 | end |
104 | 104 | |
105 | 105 | should 'display image if article is an image' do | ... | ... |
test/unit/article_test.rb
... | ... | @@ -1423,4 +1423,21 @@ class ArticleTest < Test::Unit::TestCase |
1423 | 1423 | assert_equal 'some name', a.author_name |
1424 | 1424 | end |
1425 | 1425 | |
1426 | + should 'retrieve latest info from topic when has no comments' do | |
1427 | + forum = fast_create(Forum, :name => 'Forum test', :profile_id => profile.id) | |
1428 | + post = fast_create(TextileArticle, :name => 'First post', :profile_id => profile.id, :parent_id => forum.id, :updated_at => Time.now) | |
1429 | + assert_equal post.updated_at, post.info_from_last_update[:date] | |
1430 | + assert_equal profile.name, post.info_from_last_update[:author_name] | |
1431 | + assert_equal profile.url, post.info_from_last_update[:author_url] | |
1432 | + end | |
1433 | + | |
1434 | + should 'retrieve latest info from comment when has comments' do | |
1435 | + forum = fast_create(Forum, :name => 'Forum test', :profile_id => profile.id) | |
1436 | + post = fast_create(TextileArticle, :name => 'First post', :profile_id => profile.id, :parent_id => forum.id, :updated_at => Time.now) | |
1437 | + post.comments << Comment.new(:name => 'Guest', :email => 'guest@example.com', :title => 'test comment', :body => 'hello!') | |
1438 | + assert_equal post.comments.last.created_at, post.info_from_last_update[:date] | |
1439 | + assert_equal "Guest", post.info_from_last_update[:author_name] | |
1440 | + assert_nil post.info_from_last_update[:author_url] | |
1441 | + end | |
1442 | + | |
1426 | 1443 | end | ... | ... |
test/unit/comment_test.rb
... | ... | @@ -317,4 +317,14 @@ class CommentTest < Test::Unit::TestCase |
317 | 317 | assert result[1].replies.empty? |
318 | 318 | end |
319 | 319 | |
320 | + should 'provide author url for authenticated user' do | |
321 | + author = Person.new | |
322 | + author.expects(:url).returns('http://blabla.net/author') | |
323 | + assert_equal 'http://blabla.net/author', Comment.new(:author => author).author_url | |
324 | + end | |
325 | + | |
326 | + should 'not provide author url for unauthenticated user' do | |
327 | + assert_nil Comment.new(:email => 'my@email.com').author_url | |
328 | + end | |
329 | + | |
320 | 330 | end | ... | ... |
test/unit/forum_helper_test.rb
... | ... | @@ -9,7 +9,6 @@ class ForumHelperTest < Test::Unit::TestCase |
9 | 9 | include ApplicationHelper |
10 | 10 | |
11 | 11 | def setup |
12 | - stubs(:show_date).returns('') | |
13 | 12 | @environment = Environment.default |
14 | 13 | @profile = create_user('forum_helper_test').person |
15 | 14 | @forum = fast_create(Forum, :profile_id => profile.id, :name => 'Forum test') |
... | ... | @@ -39,9 +38,9 @@ class ForumHelperTest < Test::Unit::TestCase |
39 | 38 | should 'return post update if it has no comments' do |
40 | 39 | author = create_user('forum test author').person |
41 | 40 | some_post = TextileArticle.create!(:name => 'First post', :profile => profile, :parent => forum, :published => true) |
42 | - some_post.expects(:author).returns(author) | |
41 | + some_post.expects(:author).returns(author).times(2) | |
43 | 42 | assert some_post.comments.empty? |
44 | - assert_equal "#{some_post.updated_at.to_s} ago by #{author.name}", last_topic_update(some_post) | |
43 | + assert_match /#{some_post.updated_at.to_s} ago by <a href='[^']+'>forum test author<\/a>/, last_topic_update(some_post) | |
45 | 44 | end |
46 | 45 | |
47 | 46 | should 'return last comment date if it has comments' do |
... | ... | @@ -51,27 +50,19 @@ class ForumHelperTest < Test::Unit::TestCase |
51 | 50 | some_post.comments << Comment.new(:title => 'test', :body => 'test', :author => a2) |
52 | 51 | c = Comment.last |
53 | 52 | assert_equal 2, some_post.comments.count |
54 | - assert_equal "#{c.created_at.to_s} ago by #{a2.name}", last_topic_update(some_post) | |
53 | + assert_match /#{c.created_at.to_s} ago by <a href='[^']+'>a2<\/a>/, last_topic_update(some_post) | |
55 | 54 | end |
56 | 55 | |
57 | - protected | |
58 | - | |
59 | - def will_paginate(arg1, arg2) | |
60 | - end | |
61 | - | |
62 | - def link_to(content, url) | |
63 | - content | |
56 | + should "return last comment author's name from unauthenticated user" do | |
57 | + some_post = TextileArticle.create!(:name => 'First post', :profile => profile, :parent => forum, :published => true) | |
58 | + some_post.comments << Comment.new(:name => 'John', :email => 'lenon@example.com', :title => 'test', :body => 'test') | |
59 | + c = Comment.last | |
60 | + assert_match /#{c.created_at.to_s} ago by John/m, last_topic_update(some_post) | |
64 | 61 | end |
65 | 62 | |
66 | - def tag(tag, args = {}) | |
67 | - attrs = args.map{|k,v| "#{k}='#{v}'"}.join(' ') | |
68 | - "<#{tag} #{attrs} />" | |
69 | - end | |
63 | + protected | |
70 | 64 | |
71 | - def content_tag(tag, content, options = {}) | |
72 | - tag_attr = options.blank? ? "" : options.collect{ |o| "#{o[0]}=\"#{o[1]}\"" }.join(' ') | |
73 | - "<#{tag}#{tag_attr}>#{content}</#{tag}>" | |
74 | - end | |
65 | + include NoosferoTestHelper | |
75 | 66 | |
76 | 67 | def time_ago_as_sentence(t = Time.now) |
77 | 68 | t.to_s | ... | ... |