Big changes related to mail management and events lifecycle

This commit is contained in:
echarp 2015-10-22 21:14:36 +02:00
parent a1498ac05a
commit 1b6c5e16d2
15 changed files with 103 additions and 98 deletions

View File

@ -35,7 +35,7 @@ class EventsController < ApplicationController
# POST /events.json # POST /events.json
def create def create
respond_to do |format| respond_to do |format|
if @event.save && send_creation_mails if @event.save
format.html { redirect_to :root, notice: t('.ok') } format.html { redirect_to :root, notice: t('.ok') }
# 201 means :created # 201 means :created
format.json { render action: 'show', status: 201, location: @event } format.json { render action: 'show', status: 201, location: @event }
@ -58,7 +58,7 @@ class EventsController < ApplicationController
# PATCH/PUT /events/1.json # PATCH/PUT /events/1.json
def update def update
respond_to do |format| respond_to do |format|
if @event.update(event_params) && send_update_mails if @event.update event_params
format.html { redirect_to :root, notice: t('.ok') } format.html { redirect_to :root, notice: t('.ok') }
format.json { head :no_content } format.json { head :no_content }
else else
@ -108,26 +108,14 @@ class EventsController < ApplicationController
:contact, :submitter, :tags :contact, :submitter, :tags
end end
def locked
redirect_to edit_event_url(@event, secret: @event.secret),
alert: t('staleObjectError')
end
# Check that you can only edit an existing event if you know its secret # Check that you can only edit an existing event if you know its secret
def check_secret def check_secret
redirect_to :root, alert: t(:forbidden, scope: [:events, :edit]) \ redirect_to :root, alert: t(:forbidden, scope: [:events, :edit]) \
unless params[:secret] == @event.secret unless params[:secret] == @event.secret
end end
def send_creation_mails
# Send an event creation mail to its author
EventMailer.create(@event).deliver_now
# Send a mail to moderators
ModerationMailer.create(@event).deliver_now
end
def send_update_mails
# Send an update mail to moderators
ModerationMailer.update(@event, nil).deliver_now
end
def locked
redirect_to edit_event_url(@event, secret: @event.secret),
alert: t('staleObjectError')
end
end end

View File

@ -20,7 +20,7 @@ class ModerationsController < ApplicationController
# PATCH/PUT /moderations/1.json # PATCH/PUT /moderations/1.json
def update def update
respond_to do |format| respond_to do |format|
if @moderation.update_attributes(moderation_params) && send_mails if @moderation.update_attributes moderation_params
format.html { redirect_to :moderations, notice: t('.ok') } format.html { redirect_to :moderations, notice: t('.ok') }
format.json { head :no_content } format.json { head :no_content }
else else
@ -35,7 +35,6 @@ class ModerationsController < ApplicationController
# PATCH/PUT /accept/1.json # PATCH/PUT /accept/1.json
def accept def accept
@moderation.update moderated: true @moderation.update moderated: true
send_accept_mails
respond_to do |format| respond_to do |format|
format.html { redirect_to :moderations, notice: t('.ok') } format.html { redirect_to :moderations, notice: t('.ok') }
format.json { head :no_content } format.json { head :no_content }
@ -45,7 +44,8 @@ class ModerationsController < ApplicationController
# DELETE /events/1 # DELETE /events/1
# DELETE /events/1.json # DELETE /events/1.json
def destroy def destroy
send_destroy_mails if @moderation.destroy @moderation.reason_for_deletion = get_reason_from_params params[:reason]
@moderation.destroy!
respond_to do |format| respond_to do |format|
format.html { redirect_to :moderations, notice: t('.ok') } format.html { redirect_to :moderations, notice: t('.ok') }
format.json { head :no_content } format.json { head :no_content }
@ -74,45 +74,15 @@ class ModerationsController < ApplicationController
ActionMailer::Base.default_url_options[:host] = request.host_with_port ActionMailer::Base.default_url_options[:host] = request.host_with_port
end end
def send_mails
# Send an update mail to moderators
ModerationMailer.update(@moderation, current_user).deliver_now
end
def send_accept_mails
tweet
# Send an acceptation mail to its author
EventMailer.accept(@moderation, current_user).deliver_now
# Send an acceptation mail to moderators
ModerationMailer.accept(@moderation, current_user).deliver_now
end
# Tweet this event, if configured using apache/system variables!
def tweet
client = Twitter::REST::Client.new do |config|
config.consumer_key = ENV['TWITTER_CONSUMER_KEY']
config.consumer_secret = ENV['TWITTER_CONSUMER_SECRET']
config.access_token = ENV['TWITTER_ACCESS_TOKEN']
config.access_token_secret = ENV['TWITTER_ACCESS_SECRET']
end
client.update "#{@event.to_tweet event_url(@event)}" if client.consumer_key
end
def send_destroy_mails
# Send a notification to its author
if params[:reason] == 'r_4'
@reason = params[:reason_text]
else
@reason = t "moderations.refuse.reason_#{params[:reason]}_long"
end
EventMailer.destroy(@moderation, current_user, @reason).deliver_now
ModerationMailer.destroy(@moderation, current_user, @reason).deliver_now
end
def locked def locked
redirect_to edit_moderation_url(@moderation), alert: t('staleObjectError') redirect_to edit_moderation_url(@moderation), alert: t('staleObjectError')
end end
def get_reason_from_params(reason)
if reason == 'r_4'
reason
else
t "moderations.refuse.reason_#{reason}_long"
end
end
end end

View File

@ -12,9 +12,9 @@ class EventMailer < ApplicationMailer
subject: event.title}" subject: event.title}"
end end
def accept(event, current_user) def accept(event)
@event = event @event = event
@current_user = current_user @current_user = User.find_by id: event.paper_trail_originator
mail 'In-Reply-To' => mail 'In-Reply-To' =>
"<event-#{event.id}@#{ActionMailer::Base.default_url_options[:host]}>", "<event-#{event.id}@#{ActionMailer::Base.default_url_options[:host]}>",
@ -23,10 +23,9 @@ class EventMailer < ApplicationMailer
subject: event.title}" subject: event.title}"
end end
def destroy(event, current_user, reason) def destroy(event)
@event = event @event = event
@current_user = current_user @current_user = User.find_by id: event.paper_trail_originator
@reason = reason
mail 'In-Reply-To' => mail 'In-Reply-To' =>
"<event-#{event.id}@#{ActionMailer::Base.default_url_options[:host]}>", "<event-#{event.id}@#{ActionMailer::Base.default_url_options[:host]}>",

View File

@ -11,9 +11,9 @@ class ModerationMailer < ApplicationMailer
subject: event.title}" subject: event.title}"
end end
def update(event, current_user) def update(event)
@event = event @event = event
@current_user = current_user @current_user = User.find_by id: event.paper_trail_originator
mail 'In-Reply-To' => mail 'In-Reply-To' =>
"<mod-#{event.id}@#{ActionMailer::Base.default_url_options[:host]}>", "<mod-#{event.id}@#{ActionMailer::Base.default_url_options[:host]}>",
@ -21,9 +21,9 @@ class ModerationMailer < ApplicationMailer
subject: event.title}" subject: event.title}"
end end
def accept(event, current_user) def accept(event)
@event = event @event = event
@current_user = current_user @current_user = User.find_by id: event.paper_trail_originator
mail 'In-Reply-To' => mail 'In-Reply-To' =>
"<mod-#{event.id}@#{ActionMailer::Base.default_url_options[:host]}>", "<mod-#{event.id}@#{ActionMailer::Base.default_url_options[:host]}>",
@ -31,10 +31,9 @@ class ModerationMailer < ApplicationMailer
subject: event.title}" subject: event.title}"
end end
def destroy(event, current_user, reason) def destroy(event)
@event = event @event = event
@current_user = current_user @current_user = User.find_by id: event.paper_trail_originator
@reason = reason
mail 'In-Reply-To' => mail 'In-Reply-To' =>
"<mod-#{event.id}@#{ActionMailer::Base.default_url_options[:host]}>", "<mod-#{event.id}@#{ActionMailer::Base.default_url_options[:host]}>",

View File

@ -23,6 +23,12 @@ class Event < ActiveRecord::Base
# after_validation :geocode, if: -> (obj) { obj.address_changed? } # after_validation :geocode, if: -> (obj) { obj.address_changed? }
after_validation :geocode after_validation :geocode
attr_accessor :reason_for_deletion
after_create EventCallbacks
after_update EventCallbacks
after_destroy EventCallbacks
scope :moderated, -> { where moderated: true } scope :moderated, -> { where moderated: true }
scope :unmoderated, -> { where moderated: false } scope :unmoderated, -> { where moderated: false }
scope :last_year, -> { where '? <= end_time', 1.year.ago } scope :last_year, -> { where '? <= end_time', 1.year.ago }
@ -72,19 +78,14 @@ class Event < ActiveRecord::Base
end end
before_update do before_update do
if moderated? && moderated_was != moderated self.decision_time = Time.zone.now if moderated? && moderated_changed?
self.decision_time = Time.zone.now
end
end end
def as_json(_options = {}) def as_json(_options = {})
popup = "<a href=\"/#{self.class.name.downcase.pluralize}/#{id}\"" popup = "<a href=\"/#{self.class.name.downcase.pluralize}/#{id}\""
popup += " >#{start_time.to_date} #{city}: #{title}</a>" popup += " >#{start_time.to_date} #{city}: #{title}</a>"
{ type: 'Feature', properties: { { type: 'Feature', properties: {
id: id, id: id, name: title, tags: tags, popupContent: popup
name: title,
tags: tags,
popupContent: popup
}, geometry: { }, geometry: {
type: 'Point', coordinates: [longitude, latitude] type: 'Point', coordinates: [longitude, latitude]
} } } }

View File

@ -0,0 +1,38 @@
# All the mail and tweet related callbacks to event's lifecycle
class EventCallbacks
def self.after_create(event)
EventMailer.create(event).deliver_now!
ModerationMailer.create(event).deliver_now!
end
def self.after_update(event)
if event.moderated_changed?
tweet(event)
# Send an acceptation mail to its author
EventMailer.accept(event).deliver_now
# Send an acceptation mail to moderators
ModerationMailer.accept(event).deliver_now
else
# Send an update mail to moderators
ModerationMailer.update(event).deliver_now
end
end
def self.after_destroy(event)
EventMailer.destroy(event).deliver_now
ModerationMailer.destroy(event).deliver_now
end
# Tweet this event, if configured using apache/system variables!
def self.tweet(event)
client = Twitter::REST::Client.new do |config|
config.consumer_key = ENV['TWITTER_CONSUMER_KEY']
config.consumer_secret = ENV['TWITTER_CONSUMER_SECRET']
config.access_token = ENV['TWITTER_ACCESS_TOKEN']
config.access_token_secret = ENV['TWITTER_ACCESS_SECRET']
end
client.update "#{event.to_tweet event_url(event)}" if client.consumer_key
end
end

View File

@ -1,6 +1,6 @@
= t '.body', author: @current_user = t '.body', author: @current_user
\ \
= @reason = @event.reason_for_deletion
\ \
= t '.reclamation' = t '.reclamation'
\ \

View File

@ -48,11 +48,10 @@
= raw t '.calendar_in', = raw t '.calendar_in',
rss: link_to('RSS', events_path(:rss, rss: link_to('RSS', events_path(:rss,
tag: params[:tag], region: params[:region])), tag: params[:tag], region: params[:region])),
webcal: link_to('webcal', events_path(tag: params[:tag], protocol: 'webcal', format: :ics, tag: params[:tag], webcal: link_to('webcal', events_path(tag: params[:tag],
region: params[:region])), protocol: 'webcal', format: :ics, region: params[:region])),
ical: link_to('iCal', events_path(:rss, ical: link_to('iCal', events_path(:rss,
tag: params[:tag], format: :ics, tag: params[:tag], tag: params[:tag], format: :ics, region: params[:region]))
region: params[:region]))
%a#banner(href='http://april.org/campagne') %a#banner(href='http://april.org/campagne')
-# %img(src='http://www.april.org/campagne/images/priorite-logiciel-libre-je-soutiens-april.png' -# %img(src='http://www.april.org/campagne/images/priorite-logiciel-libre-je-soutiens-april.png'

View File

@ -1,6 +1,6 @@
= t '.body', subject: @event.title, author: @current_user = t '.body', subject: @event.title, author: @current_user
\ \
= @reason = @event.reason_for_deletion
\ \
= t '.reminder' = t '.reminder'
= render file: '/events/show' = render file: '/events/show'

View File

@ -16,14 +16,16 @@ class EventMailerTest < ActionMailer::TestCase
end end
test 'accept' do test 'accept' do
mail = EventMailer.accept Event.last, User.last mail = EventMailer.accept Event.last
assert_match(/Événement .* modéré/, mail.subject) assert_match(/Événement .* modéré/, mail.subject)
assert_equal [Event.last.contact], mail.to assert_equal [Event.last.contact], mail.to
assert_equal ['moderateurs@agendadulibre.org'], mail.from assert_equal ['moderateurs@agendadulibre.org'], mail.from
end end
test 'destroy' do test 'destroy' do
mail = EventMailer.destroy Event.last, User.last, 'hello world' event = Event.last
event.reason_for_deletion = 'hello world'
mail = EventMailer.destroy Event.last
assert_match(/Événement .* refusé/, mail.subject) assert_match(/Événement .* refusé/, mail.subject)
assert_equal [Event.last.contact], mail.to assert_equal [Event.last.contact], mail.to
assert_equal ['moderateurs@agendadulibre.org'], mail.from assert_equal ['moderateurs@agendadulibre.org'], mail.from

View File

@ -25,7 +25,7 @@ class ModerationMailerTest < ActionMailer::TestCase
event.description = event.description + ' event.description = event.description + '
hello world' hello world'
mail = ModerationMailer.update event, User.last mail = ModerationMailer.update event
assert_match(/Édition de l'événement .*/, mail.subject) assert_match(/Édition de l'événement .*/, mail.subject)
assert_equal ['moderateurs@agendadulibre.org'], mail.to assert_equal ['moderateurs@agendadulibre.org'], mail.to
assert_equal ['moderateurs@agendadulibre.org'], mail.from assert_equal ['moderateurs@agendadulibre.org'], mail.from
@ -34,15 +34,16 @@ hello world'
end end
test 'accept' do test 'accept' do
mail = ModerationMailer.accept Event.unscoped.last, User.last mail = ModerationMailer.accept Event.unscoped.last
assert_match(/Événement .* modéré/, mail.subject) assert_match(/Événement .* modéré/, mail.subject)
assert_equal ['moderateurs@agendadulibre.org'], mail.to assert_equal ['moderateurs@agendadulibre.org'], mail.to
assert_equal ['moderateurs@agendadulibre.org'], mail.from assert_equal ['moderateurs@agendadulibre.org'], mail.from
end end
test 'destroy' do test 'destroy' do
mail = ModerationMailer.destroy Event.unscoped.last, User.last, event = Event.unscoped.last
'hello world' event.reason_for_deletion = 'hello world'
mail = ModerationMailer.destroy event
assert_match(/Événement .* refusé/, mail.subject) assert_match(/Événement .* refusé/, mail.subject)
assert_equal ['moderateurs@agendadulibre.org'], mail.to assert_equal ['moderateurs@agendadulibre.org'], mail.to
assert_equal ['moderateurs@agendadulibre.org'], mail.from assert_equal ['moderateurs@agendadulibre.org'], mail.from

View File

@ -9,12 +9,14 @@ class EventMailerPreview < ActionMailer::Preview
# Preview this email at http://localhost:3000/rails/mailers/event_mailer/accept # Preview this email at http://localhost:3000/rails/mailers/event_mailer/accept
def accept def accept
ActionMailer::Base.default_url_options[:host] = 'localhost:3000' ActionMailer::Base.default_url_options[:host] = 'localhost:3000'
EventMailer.accept Event.last, User.last EventMailer.accept Event.last
end end
# Preview this email at http://localhost:3000/rails/mailers/event_mailer/destroy # Preview this email at http://localhost:3000/rails/mailers/event_mailer/destroy
def destroy def destroy
ActionMailer::Base.default_url_options[:host] = 'localhost:3000' ActionMailer::Base.default_url_options[:host] = 'localhost:3000'
EventMailer.destroy Event.last, User.last, 'hello world' event = Event.last
event.reason_for_deletion = 'hello world'
EventMailer.destroy event
end end
end end

View File

@ -9,25 +9,27 @@ class ModerationMailerPreview < ActionMailer::Preview
# Preview this email at http://localhost:3000/rails/mailers/moderation_mailer/update # Preview this email at http://localhost:3000/rails/mailers/moderation_mailer/update
def update def update
ActionMailer::Base.default_url_options[:host] = 'localhost:3000' ActionMailer::Base.default_url_options[:host] = 'localhost:3000'
event = Event.last event = Event.first
event.tags += ' ho' event.tags += ' ho'
event.start_time += 1.day event.start_time += 1.day
event.description = event.description + ' event.description = event.description + '
hello world' hello world'
ModerationMailer.update event, nil ModerationMailer.update event
end end
# Preview this email at http://localhost:3000/rails/mailers/moderation_mailer/accept # Preview this email at http://localhost:3000/rails/mailers/moderation_mailer/accept
def accept def accept
ActionMailer::Base.default_url_options[:host] = 'localhost:3000' ActionMailer::Base.default_url_options[:host] = 'localhost:3000'
ModerationMailer.accept Event.last, User.last ModerationMailer.accept Event.last
end end
# Preview this email at http://localhost:3000/rails/mailers/moderation_mailer/destroy # Preview this email at http://localhost:3000/rails/mailers/moderation_mailer/destroy
def destroy def destroy
ActionMailer::Base.default_url_options[:host] = 'localhost:3000' ActionMailer::Base.default_url_options[:host] = 'localhost:3000'
ModerationMailer.destroy Event.last, User.last, 'hello world' event = Event.last
event.reason_for_deletion = 'hello world'
ModerationMailer.destroy event
end end
end end

View File

@ -24,6 +24,8 @@ class OrgaMailerPreview < ActionMailer::Preview
# Preview this email at http://localhost:3000/rails/mailers/orga_mailer/destroy # Preview this email at http://localhost:3000/rails/mailers/orga_mailer/destroy
def destroy def destroy
ActionMailer::Base.default_url_options[:host] = 'localhost:3000' ActionMailer::Base.default_url_options[:host] = 'localhost:3000'
OrgaMailer.destroy Orga.last, 'hello world' orga = Orga.last
# orga.reason_for_deletion = 'hello world'
OrgaMailer.destroy orga
end end
end end

View File

@ -3,6 +3,8 @@ require 'test_helper'
# Test events, which are the application central part # Test events, which are the application central part
class EventTest < ActiveSupport::TestCase class EventTest < ActiveSupport::TestCase
setup do setup do
ActionMailer::Base.default_url_options[:host] = 'localhost:3000'
@event = events :one @event = events :one
end end