Commit fc33a2ac authored by Rete2's avatar Rete2 Committed by Benjamin Neff

Create birthday notification and mailer

closes #7624

fixes #1649
parent 89eeec72
......@@ -6,6 +6,7 @@
* Ignore invalid `diaspora://` links [#7652](https://github.com/diaspora/diaspora/pull/7652)
## Features
* Add birthday notifications [#7624](https://github.com/diaspora/diaspora/pull/7624)
# 0.7.1.1
......
......@@ -104,7 +104,8 @@ class NotificationsController < ApplicationController
"mentioned" => "Notifications::MentionedInPost",
"mentioned_in_comment" => "Notifications::MentionedInComment",
"reshared" => "Notifications::Reshared",
"started_sharing" => "Notifications::StartedSharing"
"started_sharing" => "Notifications::StartedSharing",
"contacts_birthday" => "Notifications::ContactsBirthday"
}
end
helper_method :types
......
......@@ -16,6 +16,8 @@ module NotificationsHelper
elsif %w(Notifications::CommentOnPost Notifications::AlsoCommented Notifications::Reshared Notifications::Liked)
.include?(note.type)
opts.merge!(opts_for_post(note.linked_object))
elsif note.is_a?(Notifications::ContactsBirthday)
opts.merge!(opts_for_birthday(note.linked_object))
end
end
translation(target_type, opts)
......@@ -44,6 +46,10 @@ module NotificationsHelper
}
end
def opts_for_birthday(person)
{date: locale_date(person.birthday.to_s)}
end
def notification_people_link(note, people=nil)
actors =people || note.actors
number_of_actors = actors.size
......
# frozen_string_literal: true
module NotificationMailers
class ContactsBirthday < NotificationMailers::Base
attr_accessor :person
def set_headers(person_id)
@person = Person.find(person_id)
@headers[:subject] = I18n.t("notifier.contacts_birthday.subject", name: @person.name)
end
end
end
# frozen_string_literal: true
module Notifications
class ContactsBirthday < Notification
def mail_job
Workers::Mail::ContactsBirthday
end
def popup_translation_key
"notifications.contacts_birthday"
end
def self.notify(contact, _recipient_user_ids)
recipient = contact.user
actor = contact.person
create_notification(recipient, actor, actor).try(:email_the_user, actor, actor)
end
end
end
......@@ -14,7 +14,8 @@ class UserPreference < ApplicationRecord
"started_sharing",
"also_commented",
"liked",
"reshared"]
"reshared",
"contacts_birthday"]
def must_be_valid_email_type
unless VALID_EMAIL_TYPES.include?(self.email_type)
......
......@@ -30,6 +30,8 @@
%i.entypo-reshare
- when "started_sharing"
%i.entypo-add-user
- when "contacts_birthday"
%i.entypo-calendar
= t("." + key)
.col-md-9.stream.notifications
......
<%= t(".birthday", name: @notification.person.name) %>
[<%= t(".view_profile", name: @notification.person.name) %>][1]
[1] <%= local_or_remote_person_path(@notification.person, absolute: true) %>
......@@ -127,51 +127,55 @@
#email_prefs
- if current_user.admin?
= type.label :someone_reported, class: "checkbox-inline" do
= type.check_box :someone_reported, {checked: @email_prefs["someone_reported"]}, false, true
= type.check_box :someone_reported, {checked: email_prefs["someone_reported"]}, false, true
= t(".someone_reported")
.small-horizontal-spacer
= type.label :started_sharing, class: "checkbox-inline" do
= type.check_box :started_sharing, {checked: @email_prefs["started_sharing"]}, false, true
= type.check_box :started_sharing, {checked: email_prefs["started_sharing"]}, false, true
= t(".started_sharing")
.small-horizontal-spacer
= type.label :mentioned, class: "checkbox-inline" do
= type.check_box :mentioned, {checked: @email_prefs["mentioned"]}, false, true
= type.check_box :mentioned, {checked: email_prefs["mentioned"]}, false, true
= t(".mentioned")
.small-horizontal-spacer
= type.label :mentioned_in_comment, class: "checkbox-inline" do
= type.check_box :mentioned_in_comment, {checked: @email_prefs["mentioned_in_comment"]}, false, true
= type.check_box :mentioned_in_comment, {checked: email_prefs["mentioned_in_comment"]}, false, true
= t(".mentioned_in_comment")
.small-horizontal-spacer
= type.label :liked, class: "checkbox-inline" do
= type.check_box :liked, {checked: @email_prefs["liked"]}, false, true
= type.check_box :liked, {checked: email_prefs["liked"]}, false, true
= t(".liked")
.small-horizontal-spacer
= type.label :reshared, class: "checkbox-inline" do
= type.check_box :reshared, {checked: @email_prefs["reshared"]}, false, true
= type.check_box :reshared, {checked: email_prefs["reshared"]}, false, true
= t(".reshared")
.small-horizontal-spacer
= type.label :comment_on_post, class: "checkbox-inline" do
= type.check_box :comment_on_post, {checked: @email_prefs["comment_on_post"]}, false, true
= type.check_box :comment_on_post, {checked: email_prefs["comment_on_post"]}, false, true
= t(".comment_on_post")
.small-horizontal-spacer
= type.label :also_commented, class: "checkbox-inline" do
= type.check_box :also_commented, {checked: @email_prefs["also_commented"]}, false, true
= type.check_box :also_commented, {checked: email_prefs["also_commented"]}, false, true
= t(".also_commented")
.small-horizontal-spacer
= type.label :private_message, class: "checkbox-inline" do
= type.check_box :private_message, {checked: @email_prefs["private_message"]}, false, true
= type.check_box :private_message, {checked: email_prefs["private_message"]}, false, true
= t(".private_message")
.small-horizontal-spacer
.small-horizontal-spacer
= type.label :contacts_birthday, class: "checkbox-inline" do
= type.check_box :contacts_birthday, {checked: email_prefs["contacts_birthday"]}, false, true
= t(".birthday")
.small-horizontal-spacer
.clearfix= f.submit t(".change"), class: "btn btn-primary pull-right", id: "change_email_preferences"
%hr
......
......@@ -5,4 +5,4 @@
= render "shared/settings_nav"
.col-md-9
.framed-content
= render "edit"
= render "edit", email_prefs: @email_prefs
......@@ -5,4 +5,4 @@
.row
.col-md-12
= render "edit"
= render "edit", email_prefs: @email_prefs
# frozen_string_literal: true
module Workers
class CheckBirthday < Base
sidekiq_options queue: :low
def perform
profiles = Profile
.where("EXTRACT(MONTH FROM birthday) = ?", Time.zone.today.month)
.where("EXTRACT(DAY FROM birthday) = ?", Time.zone.today.day)
profiles.each do |profile|
profile.person.contacts.where(sharing: true, receiving: true).each do |contact|
Notifications::ContactsBirthday.notify(contact, [])
end
end
end
end
end
# frozen_string_literal: true
module Workers
module Mail
class ContactsBirthday < NotifierBase
end
end
end
......@@ -627,6 +627,10 @@ en:
zero: "%{actors} have reshared your post %{post_link}."
one: "%{actors} has reshared your post %{post_link}."
other: "%{actors} have reshared your post %{post_link}."
contacts_birthday:
zero: "%{actors} have their birthday on %{date}."
one: "%{actors} has their birthday on %{date}."
other: "%{actors} have their birthday on %{date}."
also_commented_deleted:
zero: "%{actors} commented on a deleted post."
one: "%{actors} commented on a deleted post."
......@@ -661,6 +665,7 @@ en:
mentioned_in_comment: "Mentioned in comment"
reshared: "Reshared"
started_sharing: "Started sharing"
contacts_birthday: "Birthday"
no_notifications: "You don't have any notifications yet."
and_others:
zero: "and nobody else"
......@@ -705,6 +710,10 @@ en:
reshared:
reshared: "%{name} reshared your post"
view_post: "View post >"
contacts_birthday:
subject: "%{name} has their birthday today"
birthday: "%{name} has their birthday today. Wish them 'Happy Birthday'!"
view_profile: "View %{name}’s profile"
confirm_email:
subject: "Please activate your new email address %{unconfirmed_email}"
click_link: "To activate your new email address %{unconfirmed_email}, please follow this link:"
......@@ -1198,6 +1207,7 @@ en:
comment_on_post: "someone comments on your post"
also_commented: "someone comments on a post you’ve commented on"
private_message: "you receive a private message"
birthday: "someone has their birthday"
download_export: "Download my profile"
request_export: "Request my profile data"
request_export_update: "Refresh my profile data"
......
......@@ -13,3 +13,7 @@ recurring_pod_check:
recheck_scheduled_pods:
cron: "*/30 * * * *"
class: "Workers::RecheckScheduledPods"
check_birthday:
cron: "0 0 * * *"
class: "Workers::CheckBirthday"
......@@ -81,6 +81,7 @@ describe NotificationsController, :type => :controller do
expect(response_json["unread_count_by_type"]).to eq(
"also_commented" => 1,
"comment_on_post" => 0,
"contacts_birthday" => 0,
"liked" => 0,
"mentioned" => 0,
"mentioned_in_comment" => 0,
......
......@@ -79,6 +79,23 @@ describe Notifier, type: :mailer do
end
end
describe ".contacts_birthday" do
let(:contact) { alice.contact_for(bob.person) }
let(:mail) { Notifier.send_notification("contacts_birthday", alice.id, nil, bob.person.id) }
it "TO: goes to the right person" do
expect(mail.to).to eq([alice.email])
end
it "SUBJECT: has the name of birthday person in the subject" do
expect(mail.subject).to include(bob.person.name)
end
it "has a link to the birthday profile in the body" do
expect(mail.body.encoded).to include(user_profile_url(bob.person.username))
end
end
describe ".mentioned" do
before do
@user = alice
......
# frozen_string_literal: true
describe Notifications::ContactsBirthday, type: :model do
let(:contact) { alice.contact_for(bob.person) }
let(:recipient) { alice }
let(:actor) { bob.person }
let(:birthday_notification) { Notifications::ContactsBirthday.new(recipient: alice) }
describe ".notify" do
it "calls create_notification with contact owner as a recipient" do
expect(Notifications::ContactsBirthday).to receive(:create_notification).with(recipient, actor, actor)
Notifications::ContactsBirthday.notify(contact, [])
end
it "sends an email to the contacts owner person" do
allow(Notifications::ContactsBirthday).to receive(:create_notification).and_return(birthday_notification)
expect(alice).to receive(:mail).with(Workers::Mail::ContactsBirthday, recipient.id, actor.id, actor.id)
Notifications::ContactsBirthday.notify(contact, [])
end
end
end
# frozen_string_literal: true
describe Workers::CheckBirthday do
let(:birthday_profile) { bob.profile }
let(:contact1) { alice.contact_for(bob.person) }
let(:contact2) { eve.contact_for(bob.person) }
before do
Timecop.freeze(Time.zone.local(1999, 9, 9))
birthday_profile.update_attributes(birthday: "1990-09-09")
allow(Notifications::ContactsBirthday).to receive(:notify)
end
after do
Timecop.return
end
it "calls notify method for the birthday person's contacts" do
Workers::CheckBirthday.new.perform
expect(Notifications::ContactsBirthday).to have_received(:notify).with(contact1, [])
expect(Notifications::ContactsBirthday).to have_received(:notify).with(contact2, [])
end
it "does nothing if the birthday does not exist" do
birthday_profile.update_attributes(birthday: nil)
Workers::CheckBirthday.new.perform
expect(Notifications::ContactsBirthday).not_to have_received(:notify)
end
it "does nothing if the person's birthday is not today" do
birthday_profile.update_attributes(birthday: "1988-04-15")
Workers::CheckBirthday.new.perform
expect(Notifications::ContactsBirthday).not_to have_received(:notify)
end
it "does not call notify method if a person is not a contact of the birthday person" do
contact2.destroy
Workers::CheckBirthday.new.perform
expect(Notifications::ContactsBirthday).to have_received(:notify).with(contact1, [])
expect(Notifications::ContactsBirthday).not_to have_received(:notify).with(contact2, [])
end
it "does not call notify method if a contact user is not :receiving from the birthday person" do
contact2.update_attributes(receiving: false)
Workers::CheckBirthday.new.perform
expect(Notifications::ContactsBirthday).to have_received(:notify).with(contact1, [])
expect(Notifications::ContactsBirthday).not_to have_received(:notify).with(contact2, [])
end
it "does not call notify method if a birthday person is not :sharing with the contact user" do
contact2.update_attributes(sharing: false)
Workers::CheckBirthday.new.perform
expect(Notifications::ContactsBirthday).to have_received(:notify).with(contact1, [])
expect(Notifications::ContactsBirthday).not_to have_received(:notify).with(contact2, [])
end
end
# frozen_string_literal: true
describe Workers::Mail::ContactsBirthday do
describe "#perform" do
it "should call .deliver on the notifier object" do
mail_double = double
expect(mail_double).to receive(:deliver_now)
expect(Notifier).to receive(:send_notification)
.with("contacts_birthday", alice.id).and_return(mail_double)
Workers::Mail::ContactsBirthday.new.perform(alice.id)
end
end
end
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment