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,8 +40,12 @@ module ForumHelper | ||
40 | end | 40 | end |
41 | 41 | ||
42 | def last_topic_update(article) | 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 | end | 49 | end |
46 | 50 | ||
47 | end | 51 | end |
app/models/article.rb
@@ -232,6 +232,15 @@ class Article < ActiveRecord::Base | @@ -232,6 +232,15 @@ class Article < ActiveRecord::Base | ||
232 | self.parent and self.parent.blog? | 232 | self.parent and self.parent.blog? |
233 | end | 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 | def url | 244 | def url |
236 | @url ||= self.profile.url.merge(:page => path.split('/')) | 245 | @url ||= self.profile.url.merge(:page => path.split('/')) |
237 | end | 246 | end |
app/models/comment.rb
@@ -43,6 +43,10 @@ class Comment < ActiveRecord::Base | @@ -43,6 +43,10 @@ class Comment < ActiveRecord::Base | ||
43 | author ? author.url : email | 43 | author ? author.url : email |
44 | end | 44 | end |
45 | 45 | ||
46 | + def author_url | ||
47 | + author ? author.url : nil | ||
48 | + end | ||
49 | + | ||
46 | def url | 50 | def url |
47 | article.view_url.merge(:anchor => anchor) | 51 | article.view_url.merge(:anchor => anchor) |
48 | end | 52 | end |
features/forum.feature
@@ -67,3 +67,29 @@ Feature: forum | @@ -67,3 +67,29 @@ Feature: forum | ||
67 | And I go to /joaosilva/forum-one | 67 | And I go to /joaosilva/forum-one |
68 | When I follow "Configure forum" | 68 | When I follow "Configure forum" |
69 | Then I should be on edit "Forum One" by joaosilva | 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 +6,11 @@ When /^I should not see "([^\"]+)" link$/ do |text| | ||
6 | response.should_not have_selector("a:contains('#{text}')") | 6 | response.should_not have_selector("a:contains('#{text}')") |
7 | end | 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 | Then /^I should be exactly on (.+)$/ do |page_name| | 14 | Then /^I should be exactly on (.+)$/ do |page_name| |
10 | URI.parse(current_url).request_uri.should == path_to(page_name) | 15 | URI.parse(current_url).request_uri.should == path_to(page_name) |
11 | end | 16 | end |
features/step_definitions/noosfero_steps.rb
@@ -52,9 +52,14 @@ Given /^the following (articles|events|blogs|folders|forums|galleries)$/ do |con | @@ -52,9 +52,14 @@ Given /^the following (articles|events|blogs|folders|forums|galleries)$/ do |con | ||
52 | }[content] || raise("Don't know how to build %s" % content) | 52 | }[content] || raise("Don't know how to build %s" % content) |
53 | table.hashes.map{|item| item.dup}.each do |item| | 53 | table.hashes.map{|item| item.dup}.each do |item| |
54 | owner_identifier = item.delete("owner") | 54 | owner_identifier = item.delete("owner") |
55 | + parent = item.delete("parent") | ||
55 | owner = Profile[owner_identifier] | 56 | owner = Profile[owner_identifier] |
56 | home = item.delete("homepage") | 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 | if home | 63 | if home |
59 | owner.home_page = result | 64 | owner.home_page = result |
60 | owner.save! | 65 | owner.save! |
@@ -318,8 +323,11 @@ Given /^the following comments?$/ do |table| | @@ -318,8 +323,11 @@ Given /^the following comments?$/ do |table| | ||
318 | table.hashes.each do |item| | 323 | table.hashes.each do |item| |
319 | data = item.dup | 324 | data = item.dup |
320 | article = Article.find_by_name(data.delete("article")) | 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 | comment.save! | 331 | comment.save! |
324 | end | 332 | end |
325 | end | 333 | end |
test/test_helper.rb
@@ -193,7 +193,8 @@ module NoosferoTestHelper | @@ -193,7 +193,8 @@ module NoosferoTestHelper | ||
193 | end | 193 | end |
194 | 194 | ||
195 | def content_tag(tag, content, options = {}) | 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 | end | 198 | end |
198 | 199 | ||
199 | def submit_tag(content, options = {}) | 200 | def submit_tag(content, options = {}) |
@@ -228,6 +229,8 @@ module NoosferoTestHelper | @@ -228,6 +229,8 @@ module NoosferoTestHelper | ||
228 | icon | 229 | icon |
229 | end | 230 | end |
230 | 231 | ||
232 | + def will_paginate(arg1, arg2) | ||
233 | + end | ||
231 | end | 234 | end |
232 | 235 | ||
233 | class ActionController::IntegrationTest | 236 | class ActionController::IntegrationTest |
test/unit/article_block_test.rb
@@ -89,7 +89,7 @@ class ArticleBlockTest < Test::Unit::TestCase | @@ -89,7 +89,7 @@ class ArticleBlockTest < Test::Unit::TestCase | ||
89 | block.expects(:title).returns('') | 89 | block.expects(:title).returns('') |
90 | block.stubs(:article).returns(article) | 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 | end | 93 | end |
94 | 94 | ||
95 | should "display title if defined" do | 95 | should "display title if defined" do |
@@ -99,7 +99,7 @@ class ArticleBlockTest < Test::Unit::TestCase | @@ -99,7 +99,7 @@ class ArticleBlockTest < Test::Unit::TestCase | ||
99 | block.expects(:title).returns('Article title') | 99 | block.expects(:title).returns('Article title') |
100 | block.stubs(:article).returns(article) | 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 | end | 103 | end |
104 | 104 | ||
105 | should 'display image if article is an image' do | 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,4 +1423,21 @@ class ArticleTest < Test::Unit::TestCase | ||
1423 | assert_equal 'some name', a.author_name | 1423 | assert_equal 'some name', a.author_name |
1424 | end | 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 | end | 1443 | end |
test/unit/comment_test.rb
@@ -317,4 +317,14 @@ class CommentTest < Test::Unit::TestCase | @@ -317,4 +317,14 @@ class CommentTest < Test::Unit::TestCase | ||
317 | assert result[1].replies.empty? | 317 | assert result[1].replies.empty? |
318 | end | 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 | end | 330 | end |
test/unit/forum_helper_test.rb
@@ -9,7 +9,6 @@ class ForumHelperTest < Test::Unit::TestCase | @@ -9,7 +9,6 @@ class ForumHelperTest < Test::Unit::TestCase | ||
9 | include ApplicationHelper | 9 | include ApplicationHelper |
10 | 10 | ||
11 | def setup | 11 | def setup |
12 | - stubs(:show_date).returns('') | ||
13 | @environment = Environment.default | 12 | @environment = Environment.default |
14 | @profile = create_user('forum_helper_test').person | 13 | @profile = create_user('forum_helper_test').person |
15 | @forum = fast_create(Forum, :profile_id => profile.id, :name => 'Forum test') | 14 | @forum = fast_create(Forum, :profile_id => profile.id, :name => 'Forum test') |
@@ -39,9 +38,9 @@ class ForumHelperTest < Test::Unit::TestCase | @@ -39,9 +38,9 @@ class ForumHelperTest < Test::Unit::TestCase | ||
39 | should 'return post update if it has no comments' do | 38 | should 'return post update if it has no comments' do |
40 | author = create_user('forum test author').person | 39 | author = create_user('forum test author').person |
41 | some_post = TextileArticle.create!(:name => 'First post', :profile => profile, :parent => forum, :published => true) | 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 | assert some_post.comments.empty? | 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 | end | 44 | end |
46 | 45 | ||
47 | should 'return last comment date if it has comments' do | 46 | should 'return last comment date if it has comments' do |
@@ -51,27 +50,19 @@ class ForumHelperTest < Test::Unit::TestCase | @@ -51,27 +50,19 @@ class ForumHelperTest < Test::Unit::TestCase | ||
51 | some_post.comments << Comment.new(:title => 'test', :body => 'test', :author => a2) | 50 | some_post.comments << Comment.new(:title => 'test', :body => 'test', :author => a2) |
52 | c = Comment.last | 51 | c = Comment.last |
53 | assert_equal 2, some_post.comments.count | 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 | end | 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 | end | 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 | def time_ago_as_sentence(t = Time.now) | 67 | def time_ago_as_sentence(t = Time.now) |
77 | t.to_s | 68 | t.to_s |