reshares now have notifications, slight refactor of the notification helper

This commit is contained in:
Ilyaaaaaaaaaaaaa Zhitomirskiy 2011-08-25 16:54:30 -07:00
parent e45278a043
commit 8c9a585337
23 changed files with 274 additions and 31 deletions

View file

@ -9,34 +9,18 @@ module NotificationsHelper
def object_link(note, actors)
target_type = note.popup_translation_key
actors_count = note.actors.count
if note.instance_of?(Notifications::Mentioned)
post = Mention.find(note.target_id).post
if post
if post = note.linked_object
translation(target_type, :actors => actors, :count => actors_count, :post_link => link_to(t('notifications.post'), post_path(post)).html_safe)
else
t('notifications.mentioned_deleted', :actors => actors, :count => actors_count).html_safe
t(note.deleted_translation_key, :actors => actors, :count => actors_count).html_safe
end
elsif note.instance_of?(Notifications::CommentOnPost)
post = Post.where(:id => note.target_id).first
if post
translation(target_type, :actors => actors, :count => actors_count, :post_link => link_to(t('notifications.post'), post_path(post), 'data-ref' => post.id, :class => 'hard_object_link').html_safe)
else
t('notifications.also_commented_deleted', :actors => actors, :count => actors_count).html_safe
end
elsif note.instance_of?(Notifications::AlsoCommented)
post = Post.where(:id => note.target_id).first
if post
elsif note.instance_of?(Notifications::CommentOnPost) || note.instance_of?(Notifications::AlsoCommented) || note.instance_of?(Notifications::Reshared) || note.instance_of?(Notifications::Liked)
if post = note.linked_object
translation(target_type, :actors => actors, :count => actors_count, :post_author => h(post.author.name), :post_link => link_to(t('notifications.post'), post_path(post), 'data-ref' => post.id, :class => 'hard_object_link').html_safe)
else
t('notifications.also_commented_deleted', :actors => actors, :count => actors_count).html_safe
end
elsif note.instance_of?(Notifications::Liked)
post = note.target
post = post.target if post.is_a? Like
if post
translation(target_type, :actors => actors, :count => actors_count, :post_author => h(post.author.name), :post_link => link_to(t('notifications.post'), post_path(post), 'data-ref' => post.id, :class => 'hard_object_link').html_safe)
else
t('notifications.liked_post_deleted', :actors => actors, :count => actors_count).html_safe
t(note.deleted_translation_key, :actors => actors, :count => actors_count).html_safe
end
else #Notifications:StartedSharing, etc.
translation(target_type, :actors => actors, :count => actors_count)

View file

@ -51,6 +51,19 @@ class Notifier < ActionMailer::Base
end
end
def reshared(recipient_id, sender_id, reshare_id)
@receiver = User.find_by_id(recipient_id)
@sender = Person.find_by_id(sender_id)
@reshare = Reshare.find(reshare_id)
log_mail(recipient_id, sender_id, 'reshared')
I18n.with_locale(@receiver.language) do
mail(:to => "\"#{@receiver.name}\" <#{@receiver.email}>",
:subject => I18n.t('notifier.reshared.reshared', :name => @sender.name), :host => AppConfig[:pod_uri].host)
end
end
def mentioned(recipient_id, sender_id, target_id)
@receiver = User.find_by_id(recipient_id)
@sender = Person.find_by_id(sender_id)

View file

@ -0,0 +1,11 @@
module Job
module Mail
class Reshared < Base
@queue = :mail
def self.perform(recipient_id, sender_id, reshare_id)
Notifier.reshared(recipient_id, sender_id, reshare_id).deliver
end
end
end
end

View file

@ -13,6 +13,7 @@ module Job
create_visibilities(post, recipient_user_ids)
socket_to_users(post, recipient_user_ids) if post.respond_to?(:socket_to_user)
notify_mentioned_users(post)
notify_users(post, recipient_user_ids)
end
def self.create_visibilities(post, recipient_user_ids)
@ -32,15 +33,25 @@ module Job
end
end
def self.socket_to_users(post, recipient_user_ids)
recipient_user_ids.each do |id|
post.socket_to_user(id)
end
end
def self.notify_mentioned_users(post)
post.mentions.each do |mention|
mention.notify_recipient
end
end
def self.notify_users(post, recipient_user_ids)
if post.respond_to?(:notification_type)
recipient_user_ids.each{|id|
Notification.notify(User.find(id), post, post.author)
}
end
end
end
end

View file

@ -20,6 +20,8 @@ class Notification < ActiveRecord::Base
if note_type = target.notification_type(recipient, actor)
if(target.is_a? Comment) || (target.is_a? Like)
n = note_type.concatenate_or_create(recipient, target.parent, actor, note_type)
elsif(target.is_a? Reshare)
n = note_type.concatenate_or_create(recipient, target.root, actor, note_type)
else
n = note_type.make_notification(recipient, target, actor, note_type)
end

View file

@ -2,7 +2,16 @@ class Notifications::AlsoCommented < Notification
def mail_job
Job::Mail::AlsoCommented
end
def popup_translation_key
'notifications.also_commented'
end
def deleted_translation_key
'notifications.also_commented_deleted'
end
def linked_object
Post.where(:id => self.target_id).first
end
end

View file

@ -2,7 +2,16 @@ class Notifications::CommentOnPost < Notification
def mail_job
Job::Mail::CommentOnPost
end
def popup_translation_key
'notifications.comment_on_post'
end
def deleted_translation_key
'notifications.also_commented_deleted'
end
def linked_object
Post.where(:id => self.target_id).first
end
end

View file

@ -2,7 +2,18 @@ class Notifications::Liked < Notification
def mail_job
Job::Mail::Liked
end
def popup_translation_key
'notifications.liked'
end
def deleted_translation_key
'notifications.liked_post_deleted'
end
def linked_object
post = self.target
post = post.target if post.is_a? Like
post
end
end

View file

@ -2,7 +2,16 @@ class Notifications::Mentioned < Notification
def mail_job
Job::Mail::Mentioned
end
def popup_translation_key
'notifications.mentioned'
end
def deleted_translation_key
'notifications.mentioned_deleted'
end
def linked_object
Mention.find(self.target_id).post
end
end

View file

@ -0,0 +1,18 @@
class Notifications::Reshared < Notification
def mail_job
Job::Mail::Reshared
#Job::Mail::Liked
end
def popup_translation_key
'notifications.reshared'
end
def deleted_translation_key
'notifications.reshared_post_deleted'
end
def linked_object
self.target
end
end

View file

@ -28,6 +28,11 @@ class Reshare < Post
def comment_email_subject
I18n.t('reshares.comment_email_subject', :resharer => author.name, :author => root.author.name)
end
def notification_type(user, person)
Notifications::Reshared if root.author == user.person
end
private
def after_parse

View file

@ -0,0 +1,8 @@
%p
= "#{t('.reshared', :name => "#{@sender.name}")}:"
%p{:style => "font-style:italic;color:#666"}
= post_message(@reshare.root, :process_newlines => true)
%p
= link_to t('.view_post'), post_url(@reshare)

View file

@ -0,0 +1,3 @@
!= "#{t('notifier.reshared.reshared', :name => "#{@sender.name}")}:"
!=post_message(@reshare.root)

View file

@ -379,6 +379,12 @@ en:
few: "%{actors} has just liked your %{post_link}."
many: "%{actors} has just liked your %{post_link}."
other: "%{actors} has just liked your %{post_link}."
reshared:
zero: "%{actors} has reshared your %{post_link}."
one: "%{actors} has reshared your %{post_link}."
few: "%{actors} has reshared your %{post_link}."
many: "%{actors} has reshared your %{post_link}."
other: "%{actors} has reshared your %{post_link}."
post: "post"
also_commented_deleted:
zero: "%{actors} commented on a deleted post."
@ -392,6 +398,12 @@ en:
few: "%{actors} liked your deleted post."
many: "%{actors} liked your deleted post."
other: "%{actors} liked your deleted post."
reshared_post_deleted:
zero: "%{actors} reshared your deleted post."
one: "%{actors} reshared your deleted post."
few: "%{actors} reshared your deleted post."
many: "%{actors} reshared your deleted post."
other: "%{actors} reshared your deleted post."
mentioned_deleted:
zero: "%{actors} mentioned you in a deleted post."
one: "%{actors} mentioned you in a deleted post."
@ -440,6 +452,9 @@ en:
liked:
liked: "%{name} just liked your post"
view_post: "View post >"
reshared:
reshared: "%{name} just reshared your post"
view_post: "View post >"
confirm_email:
subject: "Please activate your new email address %{unconfirmed_email}"
click_link: "To activate your new email address %{unconfirmed_email}, please click this link:"

View file

@ -7,6 +7,7 @@ Feature: Notifications
Background:
Given a user with email "bob@bob.bob"
And a user with email "alice@alice.alice"
And "alice@alice.alice" has a public post with text "check this out!"
When I sign in as "bob@bob.bob"
Scenario: someone shares with me
@ -20,10 +21,10 @@ Feature: Notifications
Then I should see "started sharing with you"
When I follow "View all"
Then I should see "started sharing with you"
And I should have 1 email delivery
Scenario: someone re-shares my post
And a user with email "bob@bob.bob" is connected with "alice@alice.alice"
And "alice@alice.alice" has a public post with text "reshare this!"
And I am on "alice@alice.alice"'s page
And I preemptively confirm the alert
And I follow "Reshare"
@ -35,6 +36,27 @@ Feature: Notifications
And I follow "notifications" in the header
And I wait for the ajax to finish
Then the notification dropdown should be visible
And I wait for the ajax to finish
Then I should see "reshared your post"
When I follow "View all"
Then I should see "reshared your post"
And I should have 1 email delivery
Scenario: someone likes my post
And a user with email "bob@bob.bob" is connected with "alice@alice.alice"
And I am on "alice@alice.alice"'s page
And I preemptively confirm the alert
And I follow "Like"
And I wait for the ajax to finish
And I go to the destroy user session page
When I sign in as "alice@alice.alice"
And I follow "notifications" in the header
And I wait for the ajax to finish
Then the notification dropdown should be visible
And I wait for the ajax to finish
Then I should see "just liked your post"
When I follow "View all"
Then I should see "just liked your post"
And I should have 1 email delivery

View file

@ -154,6 +154,10 @@ Then /^I should have (\d+) Devise email delivery$/ do |n|
Devise.mailer.deliveries.length.should == n.to_i
end
Then /^I should have (\d+) email delivery$/ do |n|
ActionMailer::Base.deliveries.length.should == n.to_i
end
When /^"([^\"]+)" has posted a status message with a photo$/ do |email|
user = User.find_for_database_authentication(:username => email)

View file

@ -17,7 +17,7 @@ Factory.define :profile do |p|
end
Factory.define :person do |p|
p.sequence(:diaspora_handle) { |n| "bob-person-#{n}#{r_str}@aol.com" }
p.sequence(:diaspora_handle) { |n| "bob-person-#{n}#{r_str}@example.net" }
p.sequence(:url) { |n| AppConfig[:pod_url] }
p.serialized_public_key OpenSSL::PKey::RSA.generate(1024).public_key.export
p.after_build do |person|

View file

@ -123,12 +123,37 @@ describe Notifier do
end
it 'can handle a activity streams photo' do
reshare = Factory(:activity_streams_photo)
like = reshare.likes.create!(:author => bob.person)
as_photo = Factory(:activity_streams_photo)
like = as_photo.likes.create!(:author => bob.person)
mail = Notifier.liked(alice.id, like.author.id, like.id)
end
end
describe ".reshared" do
before do
@sm = Factory.create(:status_message, :author => alice.person, :public => true)
@reshare = Factory.create(:reshare, :root => @sm, :author => bob.person)
@mail = Notifier.reshared(alice.id, @reshare.author.id, @reshare.id)
end
it 'TO: goes to the right person' do
@mail.to.should == [alice.email]
end
it 'BODY: contains the truncated original post' do
@mail.body.encoded.should include(@sm.formatted_message)
end
it 'BODY: contains the name of person liking' do
@mail.body.encoded.should include(@reshare.author.name)
end
it 'should not include translation fallback' do
@mail.body.encoded.should_not include(I18n.translate 'notifier.a_post_you_shared')
end
end
describe ".private_message" do
before do
@user2 = bob

View file

@ -0,0 +1,20 @@
# Copyright (c) 2010, Diaspora Inc. This file is
# licensed under the Affero General Public License version 3 or later. See
# the COPYRIGHT file.
require 'spec_helper'
describe Job::Mail::Reshared do
describe '#perfom' do
it 'should call .deliver on the notifier object' do
sm = Factory(:status_message, :author => bob.person, :public => true)
reshare = Factory.create(:reshare, :author => alice.person, :root=> sm)
mail_mock = mock()
mail_mock.should_receive(:deliver)
Notifier.should_receive(:reshared).with(bob.id, reshare.author.id, reshare.id).and_return(mail_mock)
Job::Mail::Reshared.perform(bob.id, reshare.author.id, reshare.id)
end
end
end

View file

@ -22,6 +22,10 @@ describe Job::ReceiveLocalBatch do
Job::ReceiveLocalBatch.should_receive(:notify_mentioned_users).with(@post)
Job::ReceiveLocalBatch.perform(@post.id, [bob.id])
end
it 'notifies users' do
Job::ReceiveLocalBatch.should_receive(:notify_users).with(@post, [bob.id])
Job::ReceiveLocalBatch.perform(@post.id, [bob.id])
end
end
describe '.create_visibilities' do
it 'creates a visibility for each user' do
@ -58,4 +62,20 @@ describe Job::ReceiveLocalBatch do
Job::ReceiveLocalBatch.notify_mentioned_users(@post)
end
end
describe '.notify_users' do
it 'calls notify for posts with notification type' do
reshare = Factory.create(:reshare)
Notification.should_receive(:notify)
Job::ReceiveLocalBatch.notify_users(reshare, [bob.id])
end
it 'calls notify for posts with notification type' do
sm = Factory.create(:status_message, :author => alice.person)
Notification.should_not_receive(:notify)
Job::ReceiveLocalBatch.notify_users(sm, [bob.id])
end
end
end

View file

@ -55,7 +55,7 @@ describe Notification do
Notification.notify(@user, @sm, @person)
end
context 'with a request' do
context 'with a request' do
before do
@request = Request.diaspora_initialize(:from => @user.person, :to => @user2.person, :into => @aspect)
end

View file

@ -0,0 +1,43 @@
# Copyright (c) 2010, Diaspora Inc. This file is
# licensed under the Affero General Public License version 3 or later. See
# the COPYRIGHT file.
require 'spec_helper'
describe Notifications::Reshared do
before do
@sm = Factory.create(:status_message, :author => alice.person, :public => true)
@reshare1 = Factory.create(:reshare, :root => @sm)
@reshare2 = Factory.create(:reshare, :root => @sm)
end
describe 'Notification.notify' do
it 'calls concatenate_or_create with root post' do
Notifications::Reshared.should_receive(:concatenate_or_create).with(alice, @reshare1.root, @reshare1.author, Notifications::Reshared)
Notification.notify(alice, @reshare1, @reshare1.author)
end
end
describe '#mail_job' do
it "does not raise" do
lambda{
Notifications::Reshared.new.mail_job
}.should_not raise_error
end
end
describe '#concatenate_or_create' do
it 'creates a new notification if one does not already exist' do
Notifications::Reshared.should_receive(:make_notification).with(alice, @reshare1.root, @reshare1.author, Notifications::Reshared)
Notifications::Reshared.concatenate_or_create(alice, @reshare1.root, @reshare1.author, Notifications::Reshared)
end
it "appends the actors to the aldeady existing notification" do
note = Notifications::Reshared.make_notification(alice, @reshare1.root, @reshare1.author, Notifications::Reshared)
lambda{
Notifications::Reshared.concatenate_or_create(alice, @reshare2.root, @reshare2.author, Notifications::Reshared)
}.should change(note.actors, :count).by(1)
end
end
end

View file

@ -53,14 +53,15 @@ describe Reshare do
describe '#notification_type' do
before do
@reshare = Factory.create(:reshare, :author => alice.person)
sm = Factory.create(:status_message, :author => alice.person, :public => true)
@reshare = Factory.create(:reshare, :root => sm)
end
it 'does not return anything for the author' do
it 'does not return anything for non-author of the original post' do
@reshare.notification_type(bob, @reshare.author).should be_nil
end
it 'returns private mesage for an actual receiver' do
@reshare.notification_type(alice, @reshare.author).should == Notifications::PrivateMessage
it 'returns "Reshared" for the original post author' do
@reshare.notification_type(alice, @reshare.author).should == Notifications::Reshared
end
end