Merge pull request #118 from AyuntamientoMadrid/emails-23

Sends emails
This commit is contained in:
Juanjo Bazán
2015-08-07 21:25:09 +02:00
22 changed files with 268 additions and 8 deletions

View File

@@ -59,3 +59,7 @@ group :test do
gem 'coveralls', require: false
end
group :test do
gem 'email_spec'
end

View File

@@ -114,6 +114,9 @@ GEM
json
thread
thread_safe
email_spec (1.6.0)
launchy (~> 2.1)
mail (~> 2.2)
erubis (2.7.0)
execjs (2.5.2)
factory_girl (4.5.0)
@@ -305,6 +308,7 @@ DEPENDENCIES
coveralls
database_cleaner
devise
email_spec
factory_girl_rails
foundation-rails
i18n-tasks

View File

@@ -17,7 +17,7 @@ class AccountController < ApplicationController
end
def account_params
params.require(:account).permit(:first_name, :last_name, :nickname, :use_nickname)
params.require(:account).permit(:first_name, :last_name, :nickname, :use_nickname, :email_on_debate_comment, :email_on_comment_reply)
end
end

View File

@@ -7,6 +7,10 @@ class CommentsController < ApplicationController
@comment = Comment.build(@debate, current_user, params[:comment][:body])
@comment.save!
@comment.move_to_child_of(@parent) if reply?
Mailer.comment(@comment).deliver_now if email_on_debate_comment?
Mailer.reply(@comment).deliver_now if email_on_comment_reply?
respond_with @comment
end
@@ -32,4 +36,12 @@ class CommentsController < ApplicationController
def reply?
@parent.class == Comment
end
def email_on_debate_comment?
@comment.debate.author.email_on_debate_comment?
end
def email_on_comment_reply?
reply? && @parent.author.email_on_comment_reply?
end
end

View File

@@ -0,0 +1,4 @@
class ApplicationMailer < ActionMailer::Base
default from: "participacion@madrid.es"
layout 'mailer'
end

16
app/mailers/mailer.rb Normal file
View File

@@ -0,0 +1,16 @@
class Mailer < ApplicationMailer
def comment(comment)
@comment = comment
@debate = comment.debate
mail(to: @debate.author.email, subject: t('mailer.comment.subject'))
end
def reply(reply)
@reply = reply
@debate = @reply.debate
parent = Comment.find(@reply.parent_id)
mail(to: parent.author.email, subject: t('mailer.reply.subject'))
end
end

View File

@@ -17,4 +17,13 @@ class Comment < ActiveRecord::Base
def self.find_parent(params)
params[:commentable_type].constantize.find(params[:commentable_id])
end
def debate
commentable if commentable.class == Debate
end
def author
user
end
end

View File

@@ -15,6 +15,16 @@
<%= f.label :nickname, t("account.show.nickname_label") %>
<%= f.text_field :nickname %>
<div>
<%= f.check_box :email_on_debate_comment %>
<%= f.label :email_on_debate_comment, t("account.show.email_on_debate_comment_label") %>
</div>
<div>
<%= f.check_box :email_on_comment_reply %>
<%= f.label :email_on_comment_reply, t("account.show.email_on_comment_reply_label") %>
</div>
<%= f.submit t("account.show.save_changes_submit"), class: "button radius" %>
<% end %>

View File

@@ -0,0 +1,5 @@
<html>
<body>
<%= yield %>
</body>
</html>

View File

@@ -0,0 +1,7 @@
Hello,
<div><%= @comment.author.name %></div>
<div><%= @comment.body %></div>
<div><%= link_to @debate.title, debate_url(@debate) %></div>

View File

@@ -0,0 +1,7 @@
Hello,
<div><%= @reply.author.name %></div>
<div><%= @reply.body %></div>
<div><%= link_to @debate.title, debate_url(@debate) %></div>

View File

@@ -62,6 +62,8 @@ en:
show:
title: "My account"
save_changes_submit: "Save changes"
email_on_debate_comment_label: "Receive email when someone comments on my debates"
email_on_comment_reply_label: "Receive email when someone replies to my comments"
change_credentials_link: "Change my credentials"
first_name_label: "First Name"
last_name_label: "Last Name"
@@ -73,3 +75,8 @@ en:
shared:
tags_cloud:
tags: Tags
mailer:
comment:
subject: Someone has commented on your debate
reply:
subject: Someone has replied to your comment

View File

@@ -62,6 +62,8 @@ es:
show:
title: "Mi cuenta"
save_changes_submit: "Guardar cambios"
email_on_debate_comment_label: "Recibir un email cuando alguien commenta en mis debates"
email_on_comment_reply_label: "Recibir un email cuando alguien contesta a mis comentarios"
change_credentials_link: "Cambiar mi contraseña"
first_name_label: "Nombre"
last_name_label: "Apellidos"
@@ -73,4 +75,8 @@ es:
shared:
tags_cloud:
tags: Etiquetas
mailer:
comment:
subject: Alguien ha comentado en tu debate
reply:
subject: Alguien ha respondido a tu comentario

View File

@@ -0,0 +1,6 @@
class AddPreferencesToUsers < ActiveRecord::Migration
def change
add_column :users, :email_on_debate_comment, :boolean, default: false
add_column :users, :email_on_comment_reply, :boolean, default: false
end
end

View File

@@ -11,7 +11,7 @@
#
# It's strongly recommended that you check this file into your version control system.
ActiveRecord::Schema.define(version: 20150806140048) do
ActiveRecord::Schema.define(version: 20150806163142) do
# These are extensions that must be enabled in order to support this database
enable_extension "plpgsql"
@@ -82,6 +82,8 @@ ActiveRecord::Schema.define(version: 20150806140048) do
t.string "unconfirmed_email"
t.string "nickname"
t.boolean "use_nickname", default: false, null: false
t.boolean "email_on_debate_comment", default: false
t.boolean "email_on_comment_reply", default: false
end
add_index "users", ["confirmation_token"], name: "index_users_on_confirmation_token", unique: true, using: :btree

View File

@@ -21,6 +21,8 @@ feature 'Account' do
fill_in 'account_first_name', with: 'Larry'
fill_in 'account_last_name', with: 'Bird'
check 'account_email_on_debate_comment'
check 'account_email_on_comment_reply'
click_button 'Save changes'
expect(page).to have_content "Saved"
@@ -29,5 +31,7 @@ feature 'Account' do
expect(page).to have_selector("input[value='Larry']")
expect(page).to have_selector("input[value='Bird']")
expect(page).to have_selector("input[id='account_email_on_debate_comment'][value='1']")
expect(page).to have_selector("input[id='account_email_on_comment_reply'][value='1']")
end
end

View File

@@ -41,11 +41,11 @@ feature 'Comments' do
login_as(user)
visit debate_path(debate)
fill_in 'comment_body', with: '¿Has pensado en esto...?'
fill_in 'comment_body', with: 'Have you thought about...?'
click_button 'Publish comment'
within "#comments" do
expect(page).to have_content '¿Has pensado en esto...?'
expect(page).to have_content 'Have you thought about...?'
end
end
@@ -60,12 +60,12 @@ feature 'Comments' do
click_link "Reply"
within "#js-comment-form-comment_#{comment.id}" do
fill_in 'comment_body', with: 'La semana que viene está hecho.'
fill_in 'comment_body', with: 'It will be done next week.'
click_button 'Publish reply'
end
within "#comment-#{comment.id}" do
expect(page).to have_content 'La semana que viene está hecho.'
expect(page).to have_content 'It will be done next week.'
end
end

View File

@@ -0,0 +1,63 @@
require 'rails_helper'
feature 'Emails' do
background do
reset_mailer
end
scenario "Signup Email" do
sign_up
email = open_last_email
expect(email).to have_subject('Confirmation instructions')
expect(email).to deliver_to('manuela@madrid.es')
expect(email).to have_body_text(user_confirmation_path)
end
scenario "Reset password" do
reset_password
email = open_last_email
expect(email).to have_subject('Reset password instructions')
expect(email).to deliver_to('manuela@madrid.es')
expect(email).to have_body_text(edit_user_password_path)
end
scenario "Debate comment", :js do
user = create(:user, email_on_debate_comment: true)
debate = create(:debate, author: user)
comment_on(debate)
email = open_last_email
expect(email).to have_subject('Someone has commented on your debate')
expect(email).to deliver_to(debate.author)
expect(email).to have_body_text(debate_path(debate))
end
scenario "Comment reply", :js do
user = create(:user, email_on_comment_reply: true)
reply_to(user)
email = open_last_email
expect(email).to have_subject('Someone has replied to your comment')
expect(email).to deliver_to(user)
expect(email).to have_body_text(debate_path(Comment.first.debate))
end
scenario 'Do not send email about debate comment unless set in preferences', :js do
user = create(:user, email_on_debate_comment: false)
debate = create(:debate, author: user)
comment_on(debate)
expect { open_last_email }.to raise_error "No email has been sent!"
end
scenario "Do not send email about comment reply unless set in preferences", :js do
user = create(:user, email_on_comment_reply: false)
reply_to(user)
expect { open_last_email }.to raise_error "No email has been sent!"
end
end

View File

@@ -44,4 +44,26 @@ feature 'Users' do
expect(page).to have_content 'Signed out successfully.'
end
scenario 'Reset password' do
create(:user, email: 'manuela@madrid.es')
visit '/'
click_link 'Log in'
click_link 'Forgot your password?'
fill_in 'user_email', with: 'manuela@madrid.es'
click_button 'Send me reset password instructions'
expect(page).to have_content "You will receive an email with instructions on how to reset your password in a few minutes."
sent_token = /.*reset_password_token=(.*)".*/.match(ActionMailer::Base.deliveries.last.body.to_s)[1]
visit edit_user_password_path(reset_password_token: sent_token)
fill_in 'user_password', with: 'new password'
fill_in 'user_password_confirmation', with: 'new password'
click_button 'Change my password'
expect(page).to have_content "Your password has been changed successfully. You are now signed in."
end
end

View File

@@ -34,6 +34,20 @@ describe User do
expect(subject).to be_valid
end
describe 'preferences' do
describe 'email_on_debate_comment' do
it 'should be false by default' do
expect(subject.email_on_debate_comment).to eq(false)
end
end
describe 'email_on_comment_reply' do
it 'should be false by default' do
expect(subject.email_on_comment_reply).to eq(false)
end
end
end
describe 'use_nickname' do
describe 'when true' do
before { subject.use_nickname = true }

View File

@@ -1,5 +1,7 @@
require 'factory_girl_rails'
require 'database_cleaner'
require "email_spec"
Dir["./spec/support/**/*.rb"].sort.each { |f| require f}
RSpec.configure do |config|
config.use_transactional_fixtures = false
@@ -7,7 +9,9 @@ RSpec.configure do |config|
config.filter_run :focus
config.run_all_when_everything_filtered = true
config.include FactoryGirl::Syntax::Methods
config.include(EmailSpec::Helpers)
config.include(EmailSpec::Matchers)
config.include(CommonActions)
config.before(:suite) do
DatabaseCleaner.clean_with :truncation
end

View File

@@ -0,0 +1,54 @@
module CommonActions
def sign_up
visit '/'
click_link 'Sign up'
fill_in 'user_first_name', with: 'Manuela'
fill_in 'user_last_name', with: 'Carmena'
fill_in 'user_email', with: 'manuela@madrid.es'
fill_in 'user_password', with: 'judgementday'
fill_in 'user_password_confirmation', with: 'judgementday'
click_button 'Sign up'
end
def reset_password
create(:user, email: 'manuela@madrid.es')
visit '/'
click_link 'Log in'
click_link 'Forgot your password?'
fill_in 'user_email', with: 'manuela@madrid.es'
click_button 'Send me reset password instructions'
end
def comment_on(debate)
user2 = create(:user)
login_as(user2)
visit debate_path(debate)
fill_in 'comment_body', with: 'Have you thought about...?'
click_button 'Publish comment'
expect(page).to have_content 'Have you thought about...?'
end
def reply_to(user)
manuela = create(:user)
debate = create(:debate)
comment = create(:comment, commentable: debate, user: user)
login_as(manuela)
visit debate_path(debate)
click_link "Reply"
within "#js-comment-form-comment_#{comment.id}" do
fill_in 'comment_body', with: 'It will be done next week.'
click_button 'Publish reply'
end
expect(page).to have_content 'It will be done next week.'
end
end