Commit a68225423123e7dc8ee6ed1ea8277dff75319fd0
Committed by
Antonio Terceiro
1 parent
d3ed5d29
Exists in
master
and in
29 other branches
ActionItem870: notify article owner about new comments by e-mail
Showing
8 changed files
with
136 additions
and
7 deletions
Show diff stats
app/helpers/article_helper.rb
@@ -7,8 +7,10 @@ module ArticleHelper | @@ -7,8 +7,10 @@ module ArticleHelper | ||
7 | check_box(:article, :published) + | 7 | check_box(:article, :published) + |
8 | content_tag('label', _('Published'), :for => 'article_published') + | 8 | content_tag('label', _('Published'), :for => 'article_published') + |
9 | check_box(:article, :accept_comments) + | 9 | check_box(:article, :accept_comments) + |
10 | - content_tag('label', _('Accept Comments'), :for => 'article_accept_comments') | ||
11 | - ) | 10 | + content_tag('label', _('Accept Comments'), :for => 'article_accept_comments') + |
11 | + check_box(:article, :notify_comments) + | ||
12 | + content_tag('label', _('Notify Comments'), :for => 'article_notify_comments') | ||
13 | + ) + observe_field(:article_accept_comments, :function => "$('article_notify_comments').disabled = ! $('article_accept_comments').checked") | ||
12 | end | 14 | end |
13 | 15 | ||
14 | def cms_label_for_new_children | 16 | def cms_label_for_new_children |
app/models/comment.rb
@@ -45,4 +45,26 @@ class Comment < ActiveRecord::Base | @@ -45,4 +45,26 @@ class Comment < ActiveRecord::Base | ||
45 | article.comments_updated | 45 | article.comments_updated |
46 | end | 46 | end |
47 | 47 | ||
48 | + after_create do |comment| | ||
49 | + if comment.article.notify_comments? | ||
50 | + Comment::Notifier.deliver_mail(comment) | ||
51 | + end | ||
52 | + end | ||
53 | + | ||
54 | + class Notifier < ActionMailer::Base | ||
55 | + def mail(comment) | ||
56 | + profile = comment.article.profile | ||
57 | + recipients profile.email | ||
58 | + from "#{profile.environment.name} <#{profile.environment.contact_email}>" | ||
59 | + subject _("%s - New comment in '%s'") % [profile.environment.name, comment.article.title] | ||
60 | + body :name => (comment.author.nil? ? comment.name : comment.author.name), | ||
61 | + :email => (comment.author.nil? ? comment.email : comment.author.email), | ||
62 | + :title => comment.title, | ||
63 | + :body => comment.body, | ||
64 | + :article_url => comment.article.url, | ||
65 | + :environment => profile.environment.name, | ||
66 | + :url => url_for(:host => profile.environment.default_hostname, :controller => 'home') | ||
67 | + end | ||
68 | + end | ||
69 | + | ||
48 | end | 70 | end |
@@ -0,0 +1,11 @@ | @@ -0,0 +1,11 @@ | ||
1 | +class AddNotifyCommentsToArticles < ActiveRecord::Migration | ||
2 | + def self.up | ||
3 | + add_column :articles, :notify_comments, :boolean, :default => false | ||
4 | + add_column :article_versions, :notify_comments, :boolean, :default => false | ||
5 | + end | ||
6 | + | ||
7 | + def self.down | ||
8 | + remove_column :articles, :notify_comments | ||
9 | + remove_column :article_versions, :notify_comments | ||
10 | + end | ||
11 | +end |
db/schema.rb
@@ -9,7 +9,7 @@ | @@ -9,7 +9,7 @@ | ||
9 | # | 9 | # |
10 | # It's strongly recommended to check this file into your version control system. | 10 | # It's strongly recommended to check this file into your version control system. |
11 | 11 | ||
12 | -ActiveRecord::Schema.define(:version => 56) do | 12 | +ActiveRecord::Schema.define(:version => 57) do |
13 | 13 | ||
14 | create_table "article_versions", :force => true do |t| | 14 | create_table "article_versions", :force => true do |t| |
15 | t.integer "article_id" | 15 | t.integer "article_id" |
@@ -40,6 +40,7 @@ ActiveRecord::Schema.define(:version => 56) do | @@ -40,6 +40,7 @@ ActiveRecord::Schema.define(:version => 56) do | ||
40 | t.boolean "accept_comments", :default => true | 40 | t.boolean "accept_comments", :default => true |
41 | t.integer "reference_article_id" | 41 | t.integer "reference_article_id" |
42 | t.text "setting" | 42 | t.text "setting" |
43 | + t.boolean "notify_comments", :default => false | ||
43 | end | 44 | end |
44 | 45 | ||
45 | create_table "articles", :force => true do |t| | 46 | create_table "articles", :force => true do |t| |
@@ -71,6 +72,7 @@ ActiveRecord::Schema.define(:version => 56) do | @@ -71,6 +72,7 @@ ActiveRecord::Schema.define(:version => 56) do | ||
71 | t.boolean "accept_comments", :default => true | 72 | t.boolean "accept_comments", :default => true |
72 | t.integer "reference_article_id" | 73 | t.integer "reference_article_id" |
73 | t.text "setting" | 74 | t.text "setting" |
75 | + t.boolean "notify_comments", :default => false | ||
74 | end | 76 | end |
75 | 77 | ||
76 | create_table "articles_categories", :id => false, :force => true do |t| | 78 | create_table "articles_categories", :id => false, :force => true do |t| |
@@ -79,8 +81,8 @@ ActiveRecord::Schema.define(:version => 56) do | @@ -79,8 +81,8 @@ ActiveRecord::Schema.define(:version => 56) do | ||
79 | t.boolean "virtual", :default => false | 81 | t.boolean "virtual", :default => false |
80 | end | 82 | end |
81 | 83 | ||
82 | - add_index "articles_categories", ["article_id"], :name => "index_articles_categories_on_article_id" | ||
83 | add_index "articles_categories", ["category_id"], :name => "index_articles_categories_on_category_id" | 84 | add_index "articles_categories", ["category_id"], :name => "index_articles_categories_on_category_id" |
85 | + add_index "articles_categories", ["article_id"], :name => "index_articles_categories_on_article_id" | ||
84 | 86 | ||
85 | create_table "blocks", :force => true do |t| | 87 | create_table "blocks", :force => true do |t| |
86 | t.string "title" | 88 | t.string "title" |
@@ -120,8 +122,8 @@ ActiveRecord::Schema.define(:version => 56) do | @@ -120,8 +122,8 @@ ActiveRecord::Schema.define(:version => 56) do | ||
120 | t.boolean "virtual", :default => false | 122 | t.boolean "virtual", :default => false |
121 | end | 123 | end |
122 | 124 | ||
123 | - add_index "categories_profiles", ["profile_id"], :name => "index_categories_profiles_on_profile_id" | ||
124 | add_index "categories_profiles", ["category_id"], :name => "index_categories_profiles_on_category_id" | 125 | add_index "categories_profiles", ["category_id"], :name => "index_categories_profiles_on_category_id" |
126 | + add_index "categories_profiles", ["profile_id"], :name => "index_categories_profiles_on_profile_id" | ||
125 | 127 | ||
126 | create_table "comments", :force => true do |t| | 128 | create_table "comments", :force => true do |t| |
127 | t.string "title" | 129 | t.string "title" |
@@ -188,8 +190,8 @@ ActiveRecord::Schema.define(:version => 56) do | @@ -188,8 +190,8 @@ ActiveRecord::Schema.define(:version => 56) do | ||
188 | t.datetime "updated_at" | 190 | t.datetime "updated_at" |
189 | end | 191 | end |
190 | 192 | ||
191 | - add_index "product_categorizations", ["product_id"], :name => "index_product_categorizations_on_product_id" | ||
192 | add_index "product_categorizations", ["category_id"], :name => "index_product_categorizations_on_category_id" | 193 | add_index "product_categorizations", ["category_id"], :name => "index_product_categorizations_on_category_id" |
194 | + add_index "product_categorizations", ["product_id"], :name => "index_product_categorizations_on_product_id" | ||
193 | 195 | ||
194 | create_table "products", :force => true do |t| | 196 | create_table "products", :force => true do |t| |
195 | t.integer "enterprise_id" | 197 | t.integer "enterprise_id" |
@@ -260,8 +262,8 @@ ActiveRecord::Schema.define(:version => 56) do | @@ -260,8 +262,8 @@ ActiveRecord::Schema.define(:version => 56) do | ||
260 | t.datetime "created_at" | 262 | t.datetime "created_at" |
261 | end | 263 | end |
262 | 264 | ||
263 | - add_index "taggings", ["tag_id"], :name => "index_taggings_on_tag_id" | ||
264 | add_index "taggings", ["taggable_id", "taggable_type"], :name => "index_taggings_on_taggable_id_and_taggable_type" | 265 | add_index "taggings", ["taggable_id", "taggable_type"], :name => "index_taggings_on_taggable_id_and_taggable_type" |
266 | + add_index "taggings", ["tag_id"], :name => "index_taggings_on_tag_id" | ||
265 | 267 | ||
266 | create_table "tags", :force => true do |t| | 268 | create_table "tags", :force => true do |t| |
267 | t.string "name" | 269 | t.string "name" |
test/functional/cms_controller_test.rb
@@ -746,4 +746,10 @@ class CmsControllerTest < Test::Unit::TestCase | @@ -746,4 +746,10 @@ class CmsControllerTest < Test::Unit::TestCase | ||
746 | assert_tag :tag => 'input', :attributes => {:type => 'submit', :value => 'Yes, I want.' } | 746 | assert_tag :tag => 'input', :attributes => {:type => 'submit', :value => 'Yes, I want.' } |
747 | end | 747 | end |
748 | 748 | ||
749 | + should 'display notify comments option' do | ||
750 | + a = profile.articles.create!(:name => 'test') | ||
751 | + get :edit, :profile => profile.identifier, :id => a.id | ||
752 | + assert :tag => 'input', :attributes => {:name => 'article[notify_comments]', :value => 1} | ||
753 | + end | ||
754 | + | ||
749 | end | 755 | end |
test/unit/article_test.rb
@@ -562,4 +562,9 @@ class ArticleTest < Test::Unit::TestCase | @@ -562,4 +562,9 @@ class ArticleTest < Test::Unit::TestCase | ||
562 | assert !a.belongs_to_blog? | 562 | assert !a.belongs_to_blog? |
563 | end | 563 | end |
564 | 564 | ||
565 | + should 'has comments notifier false by default' do | ||
566 | + a = Article.new | ||
567 | + assert !a.notify_comments? | ||
568 | + end | ||
569 | + | ||
565 | end | 570 | end |
@@ -0,0 +1,67 @@ | @@ -0,0 +1,67 @@ | ||
1 | +require File.dirname(__FILE__) + '/../test_helper' | ||
2 | + | ||
3 | +class CommentNotifierTest < Test::Unit::TestCase | ||
4 | + FIXTURES_PATH = File.dirname(__FILE__) + '/../fixtures' | ||
5 | + CHARSET = "utf-8" | ||
6 | + | ||
7 | + def setup | ||
8 | + ActionMailer::Base.delivery_method = :test | ||
9 | + ActionMailer::Base.perform_deliveries = true | ||
10 | + ActionMailer::Base.deliveries = [] | ||
11 | + | ||
12 | + @expected = TMail::Mail.new | ||
13 | + @expected.set_content_type "text", "plain", { "charset" => CHARSET } | ||
14 | + end | ||
15 | + | ||
16 | + should 'deliver mail after make aarticle commment' do | ||
17 | + p = create_user('user_comment_test').person | ||
18 | + a = Article.create!(:name => 'Article test', :profile => p, :notify_comments => true) | ||
19 | + assert_difference ActionMailer::Base.deliveries, :count do | ||
20 | + a.comments << Comment.new(:author => p, :title => 'test comment', :body => 'you suck!') | ||
21 | + end | ||
22 | + end | ||
23 | + | ||
24 | + should 'deliver mail to owner of article' do | ||
25 | + p = create_user('user_comment_test').person | ||
26 | + a = Article.create!(:name => 'Article test', :profile => p, :notify_comments => true) | ||
27 | + a.comments << Comment.new(:author => p, :title => 'test comment', :body => 'you suck!') | ||
28 | + sent = ActionMailer::Base.deliveries.first | ||
29 | + assert_equal [p.email], sent.to | ||
30 | + end | ||
31 | + | ||
32 | + should 'display author name in delivered mail' do | ||
33 | + p = create_user('user_comment_test').person | ||
34 | + a = Article.create!(:name => 'Article test', :profile => p, :notify_comments => true) | ||
35 | + a.comments << Comment.new(:author => p, :title => 'test comment', :body => 'you suck!') | ||
36 | + sent = ActionMailer::Base.deliveries.first | ||
37 | + assert_match /user_comment_test/, sent.body | ||
38 | + end | ||
39 | + | ||
40 | + should 'display unauthenticated author name and email in delivered mail' do | ||
41 | + p = create_user('user_comment_test').person | ||
42 | + a = Article.create!(:name => 'Article test', :profile => p, :notify_comments => true) | ||
43 | + a.comments << Comment.new(:name => 'flatline', :email => 'flatline@invalid.com', :title => 'test comment', :body => 'you suck!') | ||
44 | + sent = ActionMailer::Base.deliveries.first | ||
45 | + assert_match /flatline/, sent.body | ||
46 | + assert_match /flatline@invalid.com/, sent.body | ||
47 | + end | ||
48 | + | ||
49 | + should 'not deliver mail if notify comments is false' do | ||
50 | + p = create_user('user_comment_test').person | ||
51 | + a = Article.create!(:name => 'Article test', :profile => p, :notify_comments => false) | ||
52 | + assert_no_difference ActionMailer::Base.deliveries, :count do | ||
53 | + a.comments << Comment.new(:author => p, :title => 'test comment', :body => 'you suck!') | ||
54 | + end | ||
55 | + end | ||
56 | + | ||
57 | + private | ||
58 | + | ||
59 | + def read_fixture(action) | ||
60 | + IO.readlines("#{FIXTURES_PATH}/mail_sender/#{action}") | ||
61 | + end | ||
62 | + | ||
63 | + def encode(subject) | ||
64 | + quoted_printable(subject, CHARSET) | ||
65 | + end | ||
66 | + | ||
67 | +end |