Commit 629998e741fee1c5748c43833a458be38122063e
Committed by
Daniela Feitosa
1 parent
cc6d42c3
Exists in
master
and in
22 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 |