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 | 7 | check_box(:article, :published) + |
8 | 8 | content_tag('label', _('Published'), :for => 'article_published') + |
9 | 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 | 14 | end |
13 | 15 | |
14 | 16 | def cms_label_for_new_children | ... | ... |
app/models/comment.rb
... | ... | @@ -45,4 +45,26 @@ class Comment < ActiveRecord::Base |
45 | 45 | article.comments_updated |
46 | 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 | 70 | end | ... | ... |
... | ... | @@ -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 | 9 | # |
10 | 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 | 14 | create_table "article_versions", :force => true do |t| |
15 | 15 | t.integer "article_id" |
... | ... | @@ -40,6 +40,7 @@ ActiveRecord::Schema.define(:version => 56) do |
40 | 40 | t.boolean "accept_comments", :default => true |
41 | 41 | t.integer "reference_article_id" |
42 | 42 | t.text "setting" |
43 | + t.boolean "notify_comments", :default => false | |
43 | 44 | end |
44 | 45 | |
45 | 46 | create_table "articles", :force => true do |t| |
... | ... | @@ -71,6 +72,7 @@ ActiveRecord::Schema.define(:version => 56) do |
71 | 72 | t.boolean "accept_comments", :default => true |
72 | 73 | t.integer "reference_article_id" |
73 | 74 | t.text "setting" |
75 | + t.boolean "notify_comments", :default => false | |
74 | 76 | end |
75 | 77 | |
76 | 78 | create_table "articles_categories", :id => false, :force => true do |t| |
... | ... | @@ -79,8 +81,8 @@ ActiveRecord::Schema.define(:version => 56) do |
79 | 81 | t.boolean "virtual", :default => false |
80 | 82 | end |
81 | 83 | |
82 | - add_index "articles_categories", ["article_id"], :name => "index_articles_categories_on_article_id" | |
83 | 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 | 87 | create_table "blocks", :force => true do |t| |
86 | 88 | t.string "title" |
... | ... | @@ -120,8 +122,8 @@ ActiveRecord::Schema.define(:version => 56) do |
120 | 122 | t.boolean "virtual", :default => false |
121 | 123 | end |
122 | 124 | |
123 | - add_index "categories_profiles", ["profile_id"], :name => "index_categories_profiles_on_profile_id" | |
124 | 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 | 128 | create_table "comments", :force => true do |t| |
127 | 129 | t.string "title" |
... | ... | @@ -188,8 +190,8 @@ ActiveRecord::Schema.define(:version => 56) do |
188 | 190 | t.datetime "updated_at" |
189 | 191 | end |
190 | 192 | |
191 | - add_index "product_categorizations", ["product_id"], :name => "index_product_categorizations_on_product_id" | |
192 | 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 | 196 | create_table "products", :force => true do |t| |
195 | 197 | t.integer "enterprise_id" |
... | ... | @@ -260,8 +262,8 @@ ActiveRecord::Schema.define(:version => 56) do |
260 | 262 | t.datetime "created_at" |
261 | 263 | end |
262 | 264 | |
263 | - add_index "taggings", ["tag_id"], :name => "index_taggings_on_tag_id" | |
264 | 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 | 268 | create_table "tags", :force => true do |t| |
267 | 269 | t.string "name" | ... | ... |
test/functional/cms_controller_test.rb
... | ... | @@ -746,4 +746,10 @@ class CmsControllerTest < Test::Unit::TestCase |
746 | 746 | assert_tag :tag => 'input', :attributes => {:type => 'submit', :value => 'Yes, I want.' } |
747 | 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 | 755 | end | ... | ... |
test/unit/article_test.rb
... | ... | @@ -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 | ... | ... |