Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[WIP] 390 monthly email list revised #727

Open
wants to merge 20 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
1d425c4
Merge branch '390_monthly_email_list' of https://github.com/mz99/rund…
mz99 Jul 28, 2018
916ac70
added implementation for tests
mz99 Jul 28, 2018
94b64ed
fixed unbalanced distribution implementation
mz99 Jul 29, 2018
9b64a47
added templates to monthly email
mz99 Jul 29, 2018
efc6ae5
Added rake task, modified mailer parameters
mz99 Jul 30, 2018
3239979
removed comment from user.rb
mz99 Jul 30, 2018
ae239d2
rubocop'ed all offenses on user.rb
mz99 Jul 30, 2018
72961c9
added email subject line translations to monthly email
mz99 Jul 31, 2018
a3f9f42
added email subject line translations to monthly email
mz99 Jul 31, 2018
1310b27
Merge branch '390_monthly_email_list_revised' of https://github.com/r…
mz99 Aug 6, 2018
9cc2524
Added translation to monthly mailer. Changed mailer templates to use …
mz99 Aug 6, 2018
964d1ed
Fix syntax errors in locales
roschaefer Aug 9, 2018
4c5ee5c
Add missing test case, if last_login = nil ?
roschaefer Aug 9, 2018
de61610
Refactored method reasons_for_notifications for shorter methods
mz99 Aug 20, 2018
bdade6e
added whenever gem
mz99 Aug 20, 2018
1db6bf1
set rake mailer to email non-active users once a month
mz99 Aug 20, 2018
60b7137
added spec to check for error when user does not have last_login
mz99 Aug 20, 2018
a8703cf
subbed in Impression::BUDGET for amount
mz99 Sep 5, 2018
f101616
added in html safe <br> tag in monthly email translation for proper f…
mz99 Sep 5, 2018
b8d4dde
Merge remote-tracking branch 'origin/master' into 390_monthly_email_l…
roschaefer Jan 23, 2019
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions backend/Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ gem 'sentry-raven'
gem 'sidekiq'
gem 'sidekiq-unique-jobs'
gem 'valid_email2'
gem 'whenever'

gem 'rails'
# Bundle edge Rails instead: gem 'rails', github: 'rails/rails'
Expand Down
7 changes: 7 additions & 0 deletions backend/app/controllers/application_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ class ApplicationController < ActionController::API
before_action :set_paper_trail_whodunnit
before_action :set_locale
before_action :set_raven_context
before_action :set_last_login

def set_locale
I18n.locale = user_locale || guest_locale
Expand All @@ -25,6 +26,12 @@ def user_locale
current_user&.locale
end

def set_last_login
if current_user
current_user.update_columns(last_login: Time.current)
end
end

def set_raven_context
Raven.user_context(id: current_user.id) if current_user
Raven.extra_context(params: params.to_unsafe_h, url: request.url)
Expand Down
5 changes: 5 additions & 0 deletions backend/app/mailers/user_mailer.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,9 @@ def auth0_migration(user)
@user = user
mail(to: @user.email, subject: 'Auth0 Migration')
end

def monthly_news(user)
@user = user
mail(to: @user.email, subject: I18n.t('user_mailer.monthly_news.subject'))
end
end
11 changes: 11 additions & 0 deletions backend/app/models/user.rb
Original file line number Diff line number Diff line change
Expand Up @@ -64,4 +64,15 @@ def update_and_reverse_geocode(params)
end
save
end

def reasons_for_notifications
# Populate the "reasons" array with symbols depending on which conditions it satisfies
reasons = []
broadcasts_created_since_last_login = Broadcast.where('created_at >= ?', last_login)
reasons << :recently_created_broadcasts if broadcasts_created_since_last_login.count >= 5
distributed_sum = impressions.sum(:amount)
reasons << :no_given_amount_for_supported_broadcasts if impressions.positive.where(amount: nil).present?
reasons << :unbalanced_distribution if impressions.where(amount: Impression::BUDGET)
reasons
end
end
31 changes: 31 additions & 0 deletions backend/app/views/user_mailer/monthly_news.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
<!DOCTYPE html>
<html>
<head>
<meta content='text/html; charset=UTF-8' http-equiv='Content-Type' />
</head>
<body>
<h2><%= I18n.t('user_mailer.monthly_news.header.hello') %> <%= @user.name %>, </h2>

<p><%= I18n.t('user_mailer.monthly_news.header.welcome') %> </p>

<% if self.reasons_for_notifications.include? :recently_created_broadcasts %>
<p> <%= I18n.t('user_mailer.monthly_news.body.recently_created_broadcasts') %>
<% broadcasts_created_since_last_login.each do |b| %>
<ul><%= b.title %></ul>
<% end %>
</p>
<% end %>

<% if self.reasons_for_notifications.include? :no_given_amount_for_supported_broadcasts %>
<p> <%= I18n.t('user_mailer.monthly_news.body.no_given_amount_for_supported_broadcasts') %> </p>
<% end %>

<% if self.reasons_for_notifications.include? :unbalanced_distribution %>
<p> <%= I18n.t('user_mailer.monthly_news.body.unbalanced_distribution') %> </p>
<% end %>

<p><%= I18n.t('user_mailer.monthly_news.footer.closing') %> </p>

<p><%= I18n.t('user_mailer.monthly_news.footer.sign_off_html') %> </p>
</body>
</html>
23 changes: 23 additions & 0 deletions backend/app/views/user_mailer/monthly_news.text.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
<%= I18n.t('user_mailer.monthly_news.header.hello') %> <%= @user.name %>,

<%= I18n.t('user_mailer.monthly_news.header.welcome') %>

<% if self.reasons_for_notifications.include? :recently_created_broadcasts %>
<%= I18n.t('user_mailer.monthly_news.body.recently_created_broadcasts') %>
<% broadcasts_created_since_last_login.each do |b| %>
<%= b.title %>
<% end %>
<% end %>


<% if self.reasons_for_notifications.include? :no_given_amount_for_supported_broadcasts %>
<%= I18n.t('user_mailer.monthly_news.body.no_given_amount_for_supported_broadcasts') %>
<% end %>

<% if self.reasons_for_notifications.include? :unbalanced_distribution %>
<%= I18n.t('user_mailer.monthly_news.body.unbalanced_distribution') %>
<% end %>

<%= I18n.t('user_mailer.monthly_news.footer.closing') %>

<%= I18n.t('user_mailer.monthly_news.footer.sign_off_html') %>
1 change: 1 addition & 0 deletions backend/config/application.rb
Original file line number Diff line number Diff line change
Expand Up @@ -33,5 +33,6 @@ class Application < Rails::Application
config.filter_parameters << :password

config.active_record.schema_format = :sql
config.i18n.default_locale = :de
end
end
19 changes: 18 additions & 1 deletion backend/config/locales/de.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,24 @@ de:
has_one: Datensatz kann nicht gelöscht werden, da ein abhängiger %{record}-Datensatz
existiert.
has_many: Datensatz kann nicht gelöscht werden, da abhängige %{record} existieren.
user_mailer:
monthly_news:
subject: Neue Updates von Rundfunk Mitbestimmen
header:
hello: Hallo
welcome: 'Willkommen zu den Updates dieses Monats:'
body:
recently_created_broadcasts: 'Hier sind die neuen Sendungen, die seit Ihrer letzten Anmeldung den Rundfunk Mitbeständen hinzugefügt wurden:'
no_given_amount_for_supported_broadcasts: Offenbar haben Sie Übertragungen unterstützt, ohne Ihre Mittel für die ausgewählten Sendungen tatsächlich zu verteilen.
Bitte loggen Sie sich ein und verteilen Sie Gelder für Ihre Lieblingsprogramme!
unbalanced_distribution: Es sieht so aus, als ob Sie alle Ihre Gelder an eine bestimmte Sendung verteilt haben, sind Sie sicher,
dass das Ihre Absicht war? Wenn nicht, loggen Sie sich bitte ein und erkunden Sie weitere Sendungen, um Ihre Gelder zu verteilen.
Wenn das Ihre Absicht war, dann ignorieren Sie bitte diese Nachricht!
footer:
closing: Danke, dass Sie ein geschätztes Mitglied von Rundfunk Mitbestimmen sind! Wir hoffen, dass Sie bald zurückschauen, um diese neuen Updates zu sehen!
sign_off_html: |
Freundliche Grüße, <br>
Das Rundfunk Mitbestimmen Team
date:
abbr_day_names:
- So
Expand Down Expand Up @@ -233,4 +251,3 @@ de:
long: "%A, %d. %B %Y, %H:%M Uhr"
short: "%d. %B, %H:%M Uhr"
pm: nachmittags

19 changes: 19 additions & 0 deletions backend/config/locales/en.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,22 @@ en:
attributes:
amount:
total: Total amount of %{sum} exceeds the available budget of %{budget}
user_mailer:
monthly_news:
subject: New happenings in Rundfunk Mitbestimmen
header:
hello: Hello
welcome: "Welcome to this month's updates:"
body:
recently_created_broadcasts: 'Here are the new broadcasts added to Rundfunk Mitbestimmen since you last logged in:'
no_given_amount_for_supported_broadcasts: It looks like you have supported broadcasts without actually distributing your funds for your
selected broadcasts. Please log in and distribute funds for your favorite programs!
unbalanced_distribution: It looks like you have distributed all of your funds to one particular broadcast, are you sure
that was your intention? If not, then please log in and explore more broadcasts to distribute your funds.
If that was your intention, then please ignore this message!
footer:
closing: Thank you for being a valued member of Rundfunk Mitbestimmen! We hope you will check back soon to see
these new updates!
sign_off_html: |
Best Regards, <br>
The Rundfunk Mitbestimmen team
23 changes: 23 additions & 0 deletions backend/config/schedule.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# Use this file to easily define all of your cron jobs.
#
# It's helpful, but not entirely necessary to understand cron before proceeding.
# http://en.wikipedia.org/wiki/Cron

# Example:
#
# set :output, "/path/to/my/cron_log.log"
#
# every 2.hours do
# command "/usr/bin/some_great_command"
# runner "MyModel.some_method"
# rake "some:great:rake:task"
# end
#
# every 4.days do
# runner "AnotherModel.prune_old_records"
# end

# Learn more: http://github.com/javan/whenever
every 1.month do
rake 'monthly_news'
end
5 changes: 5 additions & 0 deletions backend/db/migrate/20180719134105_add_last_login_to_user.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
class AddLastLoginToUser < ActiveRecord::Migration[5.1]
def change
add_column :users, :last_login, :datetime
end
end
9 changes: 9 additions & 0 deletions backend/lib/tasks/monthly_mailer.rake
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
namespace :monthly_mailer do
desc "Send mail alerting non-active users new happenings on Rundfunk Mitbestimmen"

task monthly_news: :environment do
mz99 marked this conversation as resolved.
Show resolved Hide resolved
User.find_each do |user|
UserMailer.monthly_news(user).deliver_now
end
end
end
38 changes: 38 additions & 0 deletions backend/spec/models/user_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,44 @@
let(:liked_broadcast) { create(:impression, response: :positive, user: user).broadcast }
let(:unsupported_broadcast) { create(:impression, response: :neutral, user: user).broadcast }

describe '#reasons_for_notifications' do
subject { user.reasons_for_notifications }

context 'by default' do
it { is_expected.to be_empty }
end

context 'given a last_login timestamp' do
before do
user.update_columns(last_login: Time.current)
mz99 marked this conversation as resolved.
Show resolved Hide resolved
end
it { is_expected.to be_empty }
end

context 'many new broadcasts since last login' do
before do
user.update_columns(last_login: 2.months.ago)
create_list(:broadcast, 20)
end
it { is_expected.to include(:recently_created_broadcasts) }
end

context 'forgot to distribute money for supported broadcasts' do
before { create_list(:impression, 3, user: user, response: :positive, amount: nil) }
it { is_expected.to include(:no_given_amount_for_supported_broadcasts) }
end

context 'quite an unbalanced distribution, was it on purpose?' do
before { create(:impression, user: user, response: :positive, amount: Impression::BUDGET) }
it { is_expected.to include(:unbalanced_distribution) }
end

context 'error occurs when user has not logged in before' do
before { create(user: user, last_login: nil) }
it { is_expected.to raise_error 'NilPointerException' }
end
end

describe 'update_and_reverse_geocode' do
subject { user.update_and_reverse_geocode(params) }
let(:user) { create(:user) }
Expand Down