parent
89eeec72d3
commit
fc33a2ac5d
20 changed files with 216 additions and 14 deletions
|
|
@ -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
|
||||
|
|
|
|||
12
app/mailers/notification_mailers/contacts_birthday.rb
Normal file
12
app/mailers/notification_mailers/contacts_birthday.rb
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
# 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
|
||||
19
app/models/notifications/contacts_birthday.rb
Normal file
19
app/models/notifications/contacts_birthday.rb
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
# 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
|
||||
|
|
|
|||
6
app/views/notifier/contacts_birthday.markerb
Normal file
6
app/views/notifier/contacts_birthday.markerb
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
|
||||
<%= 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
|
||||
|
|
|
|||
18
app/workers/check_birthday.rb
Normal file
18
app/workers/check_birthday.rb
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
# 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
|
||||
8
app/workers/mail/contacts_birthday.rb
Normal file
8
app/workers/mail/contacts_birthday.rb
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
# 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
|
||||
|
|
|
|||
23
spec/models/notifications/contacts_birthday_spec.rb
Normal file
23
spec/models/notifications/contacts_birthday_spec.rb
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
# 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
|
||||
56
spec/workers/check_birthday_spec.rb
Normal file
56
spec/workers/check_birthday_spec.rb
Normal file
|
|
@ -0,0 +1,56 @@
|
|||
# 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
|
||||
13
spec/workers/mail/contacts_birthday_spec.rb
Normal file
13
spec/workers/mail/contacts_birthday_spec.rb
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
# 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
|
||||
Loading…
Reference in a new issue