diff --git a/README.md b/README.md index 9226ba87..2ffb0ae2 100644 --- a/README.md +++ b/README.md @@ -30,6 +30,7 @@ It has been heavely inspired by [Canny.io](https://canny.io/) ("astuto", indeed, * Boards, to divide different types of feedback * Roadmap, to let your users know what you're working on * Comments, to discuss with your customers +* Notifications, to inform post owner of comments * Feedback labels, to inform about the state of a certain feedback * Feedback updates, to notify your users with news regarding a certain feedback * Completely customizable (i.e. you can add/edit/remove as many boards, feedback statuses as you want; you can configure the roadmap the way you want; etc.) diff --git a/app/controllers/comments_controller.rb b/app/controllers/comments_controller.rb index 44239a0a..80c55139 100644 --- a/app/controllers/comments_controller.rb +++ b/app/controllers/comments_controller.rb @@ -1,6 +1,6 @@ class CommentsController < ApplicationController before_action :authenticate_user!, only: [:create, :update] - + def index comments = Comment .select( @@ -23,6 +23,8 @@ class CommentsController < ApplicationController comment = Comment.new(comment_params) if comment.save + send_notifications(comment) + render json: comment.attributes.merge( { user_full_name: current_user.full_name, user_email: current_user.email} ), status: :created @@ -55,14 +57,19 @@ class CommentsController < ApplicationController end private + def comment_params + params + .require(:comment) + .permit(:body, :parent_id, :is_post_update) + .merge( + user_id: current_user.id, + post_id: params[:post_id] + ) + end - def comment_params - params - .require(:comment) - .permit(:body, :parent_id, :is_post_update) - .merge( - user_id: current_user.id, - post_id: params[:post_id] - ) + def send_notifications(comment) + if comment.post.user.notifications_enabled? + UserMailer.notify_post_owner(comment: comment).deliver_later end + end end diff --git a/app/mailers/user_mailer.rb b/app/mailers/user_mailer.rb new file mode 100644 index 00000000..2369ea7f --- /dev/null +++ b/app/mailers/user_mailer.rb @@ -0,0 +1,10 @@ +class UserMailer < ApplicationMailer + default from: "notifications@example.com" + + def notify_post_owner(comment:) + @comment = comment + @user = comment.post.user + + mail(to: @user.email, subject: "[#{ENV.fetch('APP_NAME')}] - New comment on #{comment.post.title}") + end +end \ No newline at end of file diff --git a/app/views/user_mailer/notify_post_owner.html.erb b/app/views/user_mailer/notify_post_owner.html.erb new file mode 100644 index 00000000..6cc6eae1 --- /dev/null +++ b/app/views/user_mailer/notify_post_owner.html.erb @@ -0,0 +1,17 @@ + + + + + + +

Hello, <%= @user.full_name %>

+

+ There is a new comment by <%= @comment.user.full_name %> on your post <%= @comment.post.title %> +

+

To see this comment, <%= link_to "Click here", post_url(@comment.post) %>

+

Have a great day!

+ + + diff --git a/config/environments/test.rb b/config/environments/test.rb index 3b7f2e37..e0027ca3 100644 --- a/config/environments/test.rb +++ b/config/environments/test.rb @@ -9,7 +9,6 @@ ENV["POSTS_PER_PAGE"] = "15" Rails.application.configure do # Settings specified here will take precedence over those in config/application.rb. - # For Devise config.action_mailer.default_url_options = { host: 'localhost:3000' } @@ -46,6 +45,7 @@ Rails.application.configure do # The :test delivery method accumulates sent emails in the # ActionMailer::Base.deliveries array. config.action_mailer.delivery_method = :test + config.active_job.queue_adapter = :test # Print deprecation notices to the stderr. config.active_support.deprecation = :stderr diff --git a/spec/mailers/previews/user_mailer_preview.rb b/spec/mailers/previews/user_mailer_preview.rb new file mode 100644 index 00000000..3148bfc9 --- /dev/null +++ b/spec/mailers/previews/user_mailer_preview.rb @@ -0,0 +1,6 @@ +# Preview all emails at http://localhost:3000/rails/mailers/user_mailer +class UserMailerPreview < ActionMailer::Preview + def notify_post_owner + UserMailer.notify_post_owner(comment: Comment.first) + end +end diff --git a/spec/mailers/user_mailer_spec.rb b/spec/mailers/user_mailer_spec.rb new file mode 100644 index 00000000..c64ee6e4 --- /dev/null +++ b/spec/mailers/user_mailer_spec.rb @@ -0,0 +1,22 @@ +require "rails_helper" + +RSpec.describe UserMailer, type: :mailer do + describe "notify_comment" do + let(:user) { FactoryBot.create(:user, email: "notified@example.com", notifications_enabled: true) } + let(:post) { FactoryBot.create(:post, user: user)} + let(:comment) { FactoryBot.create(:comment, post: post) } + let(:mail) { UserMailer.notify_post_owner(comment: comment) } + + it "renders the headers" do + expect(mail.subject).to eq("[#{ENV.fetch('APP_NAME')}] - New comment on #{post.title}") + expect(mail.to).to eq(["notified@example.com"]) + expect(mail.from).to eq(["notifications@example.com"]) + end + + it "renders the body" do + expect(mail.body.encoded).to include("Hello, #{user.full_name}") + expect(mail.body.encoded).to include("There is a new comment by") + expect(mail.body.encoded).to include('Annoyed ? You can turn off notifications here') + end + end +end diff --git a/spec/support/action_mailer.rb b/spec/support/action_mailer.rb new file mode 100644 index 00000000..b9563a3b --- /dev/null +++ b/spec/support/action_mailer.rb @@ -0,0 +1,5 @@ +RSpec.configure do |config| + config.before(:each) do + ActionMailer::Base.deliveries.clear + end +end diff --git a/spec/system/comments_spec.rb b/spec/system/comments_spec.rb index 350c9cd4..539880ac 100644 --- a/spec/system/comments_spec.rb +++ b/spec/system/comments_spec.rb @@ -108,4 +108,34 @@ feature 'comments', type: :system, js: true do expect(Comment.where(post_id: post.id).count).to eq(comments_count + 1) end -end \ No newline at end of file + + it 'notifies post owner when comment is posted' do + log_in_as user + visit post_path(post) + allow(UserMailer).to receive_message_chain(:notify_post_owner, :deliver_later) + + comment_body = 'this is a comment!' + + find(newCommentBodySelector).fill_in with: comment_body + click_button 'Submit' + visit post_path(post) + + expect(UserMailer).to have_received(:notify_post_owner) + end + + it 'does not notify the post owner if he refused notifications' do + post_owner = FactoryBot.create(:user, notifications_enabled: false) + post = FactoryBot.create(:post, user: post_owner) + log_in_as user + visit post_path(post) + allow(UserMailer).to receive_message_chain(:notify_post_owner, :deliver_later) + + comment_body = 'this is a comment!' + + find(newCommentBodySelector).fill_in with: comment_body + click_button 'Submit' + visit post_path(post) + + expect(UserMailer).not_to have_received(:notify_post_owner) + end +end diff --git a/spec/system/user_sign_up_spec.rb b/spec/system/user_sign_up_spec.rb index 8ac4241f..0f604cde 100644 --- a/spec/system/user_sign_up_spec.rb +++ b/spec/system/user_sign_up_spec.rb @@ -77,7 +77,7 @@ feature 'sign up', type: :system do expect(page).to have_css('.alert') end - scenario 'and disables notifications' do + scenario 'with disabled notifications' do visit new_user_registration_path fill_in 'Full name', with: user.full_name fill_in 'Email', with: user.email