Refactor notification to have subclasses, just a start
This commit is contained in:
parent
809ee8a678
commit
1c1fba63e7
14 changed files with 47 additions and 42 deletions
|
|
@ -1,26 +1,26 @@
|
||||||
module NotificationsHelper
|
module NotificationsHelper
|
||||||
def object_link(note)
|
def object_link(note)
|
||||||
target_type = note.action
|
target_type = note.class
|
||||||
case target_type
|
case target_type
|
||||||
when 'mentioned'
|
when Notifications::Mentioned
|
||||||
post = Mention.find(note.target_id).post
|
post = Mention.find(note.target_id).post
|
||||||
if post
|
if post
|
||||||
"#{translation(target_type)} #{link_to t('notifications.post'), object_path(post)}".html_safe
|
"#{translation(target_type)} #{link_to t('notifications.post'), object_path(post)}".html_safe
|
||||||
else
|
else
|
||||||
"#{translation(target_type)} #{t('notifications.deleted')} #{t('notifications.post')}"
|
"#{translation(target_type)} #{t('notifications.deleted')} #{t('notifications.post')}"
|
||||||
end
|
end
|
||||||
when 'request_accepted'
|
when Notifications::RequestAccepted
|
||||||
translation(target_type)
|
translation(target_type)
|
||||||
when 'new_request'
|
when Notifications::NewRequest
|
||||||
translation(target_type)
|
translation(target_type)
|
||||||
when 'comment_on_post'
|
when Notifications::CommentOnPost
|
||||||
post = Post.where(:id => note.target_id).first
|
post = Post.where(:id => note.target_id).first
|
||||||
if post
|
if post
|
||||||
"#{translation(target_type)} #{link_to t('notifications.post'), object_path(post)}".html_safe
|
"#{translation(target_type)} #{link_to t('notifications.post'), object_path(post)}".html_safe
|
||||||
else
|
else
|
||||||
"#{translation(target_type)} #{t('notifications.deleted')} #{t('notifications.post')}"
|
"#{translation(target_type)} #{t('notifications.deleted')} #{t('notifications.post')}"
|
||||||
end
|
end
|
||||||
when 'also_commented'
|
when Notifications::AlsoCommented
|
||||||
post = Post.where(:id => note.target_id).first
|
post = Post.where(:id => note.target_id).first
|
||||||
if post
|
if post
|
||||||
"#{translation(target_type, post.person.name)} #{link_to t('notifications.post'), object_path(post)}".html_safe
|
"#{translation(target_type, post.person.name)} #{link_to t('notifications.post'), object_path(post)}".html_safe
|
||||||
|
|
|
||||||
|
|
@ -44,9 +44,9 @@ class Comment < ActiveRecord::Base
|
||||||
|
|
||||||
def notification_type(user, person)
|
def notification_type(user, person)
|
||||||
if self.post.person == user.person
|
if self.post.person == user.person
|
||||||
return "comment_on_post"
|
return Notifications::CommentOnPost
|
||||||
elsif self.post.comments.where(:person_id => user.person.id) != [] && self.person_id != user.person.id
|
elsif self.post.comments.where(:person_id => user.person.id) != [] && self.person_id != user.person.id
|
||||||
return "also_commented"
|
return Notifications::AlsoCommented
|
||||||
else
|
else
|
||||||
return false
|
return false
|
||||||
end
|
end
|
||||||
|
|
|
||||||
|
|
@ -19,7 +19,7 @@ class Mention < ActiveRecord::Base
|
||||||
|
|
||||||
|
|
||||||
def notification_type(*args)
|
def notification_type(*args)
|
||||||
'mentioned'
|
Notifications::Mentioned
|
||||||
end
|
end
|
||||||
|
|
||||||
def delete_notification
|
def delete_notification
|
||||||
|
|
|
||||||
|
|
@ -17,11 +17,11 @@ class Notification < ActiveRecord::Base
|
||||||
|
|
||||||
def self.notify(recipient, target, actor)
|
def self.notify(recipient, target, actor)
|
||||||
if target.respond_to? :notification_type
|
if target.respond_to? :notification_type
|
||||||
if action = target.notification_type(recipient, actor)
|
if note_type = target.notification_type(recipient, actor)
|
||||||
if target.is_a? Comment
|
if target.is_a? Comment
|
||||||
n = concatenate_or_create(recipient, target.post, actor, action)
|
n = concatenate_or_create(recipient, target.post, actor, note_type)
|
||||||
else
|
else
|
||||||
n = make_notification(recipient, target, actor, action)
|
n = make_notification(recipient, target, actor, note_type)
|
||||||
end
|
end
|
||||||
n.email_the_user(target, actor) if n
|
n.email_the_user(target, actor) if n
|
||||||
n.socket_to_user(recipient, :actor => actor) if n
|
n.socket_to_user(recipient, :actor => actor) if n
|
||||||
|
|
@ -33,12 +33,14 @@ class Notification < ActiveRecord::Base
|
||||||
def email_the_user(target, actor)
|
def email_the_user(target, actor)
|
||||||
self.recipient.mail(self.mail_job, self.recipient_id, actor.id, target.id)
|
self.recipient.mail(self.mail_job, self.recipient_id, actor.id, target.id)
|
||||||
end
|
end
|
||||||
|
def mail_job
|
||||||
|
raise NotImplementedError.new('Subclass this.')
|
||||||
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
def self.concatenate_or_create(recipient, target, actor, action)
|
def self.concatenate_or_create(recipient, target, actor, notification_type)
|
||||||
if n = Notification.where(:target_id => target.id,
|
if n = notification_type.where(:target_id => target.id,
|
||||||
:target_type => target.class.base_class,
|
:target_type => target.class.base_class,
|
||||||
:action => action,
|
|
||||||
:recipient_id => recipient.id).first
|
:recipient_id => recipient.id).first
|
||||||
unless n.actors.include?(actor)
|
unless n.actors.include?(actor)
|
||||||
n.actors << actor
|
n.actors << actor
|
||||||
|
|
@ -48,13 +50,12 @@ private
|
||||||
n.save!
|
n.save!
|
||||||
n
|
n
|
||||||
else
|
else
|
||||||
make_notification(recipient, target, actor, action)
|
make_notification(recipient, target, actor, notification_type)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def self.make_notification(recipient, target, actor, action)
|
def self.make_notification(recipient, target, actor, notification_type)
|
||||||
n = Notification.new(:target => target,
|
n = notification_type.new(:target => target,
|
||||||
:action => action,
|
|
||||||
:recipient_id => recipient.id)
|
:recipient_id => recipient.id)
|
||||||
n.actors << actor
|
n.actors << actor
|
||||||
n.unread = false if target.is_a? Request
|
n.unread = false if target.is_a? Request
|
||||||
|
|
|
||||||
|
|
@ -56,9 +56,9 @@ class Request < ActiveRecord::Base
|
||||||
|
|
||||||
def notification_type(user, person)
|
def notification_type(user, person)
|
||||||
if Contact.where(:user_id => user.id, :person_id => person.id).first
|
if Contact.where(:user_id => user.id, :person_id => person.id).first
|
||||||
"request_accepted"
|
Notifications::RequestAccepted
|
||||||
else
|
else
|
||||||
"new_request"
|
Notifications::NewRequest
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -8,8 +8,8 @@ class NotificationSubclasses < ActiveRecord::Migration
|
||||||
:mentioned => 'Notifications::Mentioned'
|
:mentioned => 'Notifications::Mentioned'
|
||||||
}.each_pair do |key, value|
|
}.each_pair do |key, value|
|
||||||
execute("UPDATE notifications
|
execute("UPDATE notifications
|
||||||
set type = #{value}
|
set type = '#{value}'
|
||||||
where action = #{key.to_s}")
|
where action = '#{key.to_s}'")
|
||||||
end
|
end
|
||||||
remove_column :notifications, :action
|
remove_column :notifications, :action
|
||||||
end
|
end
|
||||||
|
|
@ -23,8 +23,9 @@ class NotificationSubclasses < ActiveRecord::Migration
|
||||||
:mentioned => 'Notifications::Mentioned'
|
:mentioned => 'Notifications::Mentioned'
|
||||||
}.each_pair do |key, value|
|
}.each_pair do |key, value|
|
||||||
execute("UPDATE notifications
|
execute("UPDATE notifications
|
||||||
set action = #{key.to_s}
|
set action = '#{key.to_s}'
|
||||||
where type = #{value}")
|
where type = '#{value}'")
|
||||||
|
end
|
||||||
remove_column :notifications, :type
|
remove_column :notifications, :type
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
||||||
|
|
@ -318,10 +318,10 @@ ActiveRecord::Schema.define(:version => 20110228201109) do
|
||||||
t.string "target_type"
|
t.string "target_type"
|
||||||
t.integer "target_id"
|
t.integer "target_id"
|
||||||
t.integer "recipient_id", :null => false
|
t.integer "recipient_id", :null => false
|
||||||
t.string "action", :null => false
|
|
||||||
t.boolean "unread", :default => true, :null => false
|
t.boolean "unread", :default => true, :null => false
|
||||||
t.datetime "created_at"
|
t.datetime "created_at"
|
||||||
t.datetime "updated_at"
|
t.datetime "updated_at"
|
||||||
|
t.string "type"
|
||||||
end
|
end
|
||||||
|
|
||||||
add_index "notifications", ["recipient_id"], :name => "index_notifications_on_recipient_id"
|
add_index "notifications", ["recipient_id"], :name => "index_notifications_on_recipient_id"
|
||||||
|
|
|
||||||
|
|
@ -92,10 +92,10 @@ end
|
||||||
Factory.define(:notification) do |n|
|
Factory.define(:notification) do |n|
|
||||||
n.association :recipient, :factory => :user
|
n.association :recipient, :factory => :user
|
||||||
n.association :target, :factory => :comment
|
n.association :target, :factory => :comment
|
||||||
|
n.type 'Notifications::AlsoCommented'
|
||||||
|
|
||||||
n.after_build do |note|
|
n.after_build do |note|
|
||||||
note.actors << Factory.build( :person )
|
note.actors << Factory.build( :person )
|
||||||
note.action = note.target.notification_type(note.recipient, note.actors.first)
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -20,7 +20,7 @@ describe Comment do
|
||||||
|
|
||||||
it "returns 'comment_on_post' if the comment is on a post you own" do
|
it "returns 'comment_on_post' if the comment is on a post you own" do
|
||||||
comment = bob.comment("why so formal?", :on => @alices_post)
|
comment = bob.comment("why so formal?", :on => @alices_post)
|
||||||
comment.notification_type(alice, bob.person).should == 'comment_on_post'
|
comment.notification_type(alice, bob.person).should == Notifications::CommentOnPost
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'returns false if the comment is not on a post you own and no one "also_commented"' do
|
it 'returns false if the comment is not on a post you own and no one "also_commented"' do
|
||||||
|
|
@ -39,7 +39,7 @@ describe Comment do
|
||||||
end
|
end
|
||||||
|
|
||||||
it "returns 'also_commented' if another person commented on a post you commented on" do
|
it "returns 'also_commented' if another person commented on a post you commented on" do
|
||||||
@comment.notification_type(bob, alice.person).should == 'also_commented'
|
@comment.notification_type(bob, alice.person).should == Notifications::AlsoCommented
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
||||||
|
|
@ -21,7 +21,7 @@ describe Mention do
|
||||||
@m.save
|
@m.save
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'should only notify if the person is local' do
|
it 'should only notify if the person is local' do
|
||||||
m = Mention.new(:person => Factory(:person), :post => @sm)
|
m = Mention.new(:person => Factory(:person), :post => @sm)
|
||||||
Notification.should_not_receive(:notify)
|
Notification.should_not_receive(:notify)
|
||||||
m.save
|
m.save
|
||||||
|
|
@ -44,10 +44,10 @@ describe Mention do
|
||||||
|
|
||||||
describe '#notification_type' do
|
describe '#notification_type' do
|
||||||
it "returns 'mentioned'" do
|
it "returns 'mentioned'" do
|
||||||
Mention.new.notification_type.should == 'mentioned'
|
Mention.new.notification_type.should == Notifications::Mentioned
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
describe 'after destroy' do
|
describe 'after destroy' do
|
||||||
it 'destroys a notification' do
|
it 'destroys a notification' do
|
||||||
@user = alice
|
@user = alice
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,7 @@ describe Notification do
|
||||||
@aspect = @user.aspects.create(:name => "dudes")
|
@aspect = @user.aspects.create(:name => "dudes")
|
||||||
@opts = {:target_id => @sm.id,
|
@opts = {:target_id => @sm.id,
|
||||||
:target_type => @sm.class.name,
|
:target_type => @sm.class.name,
|
||||||
:action => "comment_on_post",
|
:type => 'Notifications::CommentOnPost',
|
||||||
:actors => [@person],
|
:actors => [@person],
|
||||||
:recipient_id => @user.id}
|
:recipient_id => @user.id}
|
||||||
@note = Notification.new(@opts)
|
@note = Notification.new(@opts)
|
||||||
|
|
@ -61,11 +61,10 @@ describe Notification do
|
||||||
it 'sockets to the recipient' do
|
it 'sockets to the recipient' do
|
||||||
opts = {:target_id => @request.id,
|
opts = {:target_id => @request.id,
|
||||||
:target_type => "Request",
|
:target_type => "Request",
|
||||||
:action => @request.notification_type(@user, @person),
|
|
||||||
:actors => [@person],
|
:actors => [@person],
|
||||||
:recipient_id => @user.id}
|
:recipient_id => @user.id}
|
||||||
|
|
||||||
n = Notification.create(opts)
|
n = @request.notification_type(@user, @person).create(opts)
|
||||||
Notification.stub!(:make_notification).and_return n
|
Notification.stub!(:make_notification).and_return n
|
||||||
|
|
||||||
n.should_receive(:socket_to_user).once
|
n.should_receive(:socket_to_user).once
|
||||||
|
|
@ -75,15 +74,14 @@ describe Notification do
|
||||||
describe '#emails_the_user' do
|
describe '#emails_the_user' do
|
||||||
it 'calls mail' do
|
it 'calls mail' do
|
||||||
opts = {
|
opts = {
|
||||||
:action => "new_request",
|
|
||||||
:actors => [@person],
|
:actors => [@person],
|
||||||
:recipient_id => @user.id}
|
:recipient_id => @user.id}
|
||||||
|
|
||||||
n = Notification.new(opts)
|
n = Notifications::NewRequest.new(opts)
|
||||||
n.stub!(:recipient).and_return @user
|
n.stub!(:recipient).and_return @user
|
||||||
|
|
||||||
@user.should_receive(:mail)
|
@user.should_receive(:mail)
|
||||||
n.email_the_user("mock", @person)
|
n.email_the_user(@request, @person)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -56,11 +56,11 @@ describe Request do
|
||||||
end
|
end
|
||||||
it "returns 'request_accepted' if there is a pending contact" do
|
it "returns 'request_accepted' if there is a pending contact" do
|
||||||
Contact.create(:user_id => @user.id, :person_id => @person.id)
|
Contact.create(:user_id => @user.id, :person_id => @person.id)
|
||||||
@request.notification_type(@user, @person).should == "request_accepted"
|
@request.notification_type(@user, @person).should == Notifications::RequestAccepted
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'returns new_request if there is not a pending contact' do
|
it 'returns new_request if there is not a pending contact' do
|
||||||
@request.notification_type(@user, @person).should == "new_request"
|
@request.notification_type(@user, @person).should == Notifications::NewRequest
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -67,7 +67,7 @@ describe Diaspora::UserModules::Connecting do
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'enqueues a mail job' do
|
it 'enqueues a mail job' do
|
||||||
Resque.should_receive(:enqueue).with(Job::MailRequestReceived, user.id, person.id)
|
Resque.should_receive(:enqueue).with(Job::MailRequestReceived, user.id, person.id, anything)
|
||||||
zord = Postzord::Receiver.new(user, :object => @r, :person => person)
|
zord = Postzord::Receiver.new(user, :object => @r, :person => person)
|
||||||
zord.receive_object
|
zord.receive_object
|
||||||
end
|
end
|
||||||
|
|
@ -87,7 +87,7 @@ describe Diaspora::UserModules::Connecting do
|
||||||
Request.where(:sender_id => user2.person.id, :recipient_id => user.person.id).should be_empty
|
Request.where(:sender_id => user2.person.id, :recipient_id => user.person.id).should be_empty
|
||||||
end
|
end
|
||||||
it 'enqueues a mail job' do
|
it 'enqueues a mail job' do
|
||||||
Resque.should_receive(:enqueue).with(Job::MailRequestAcceptance, user.id, user2.person.id).once
|
Resque.should_receive(:enqueue).with(Job::MailRequestAcceptance, user.id, user2.person.id, nil).once
|
||||||
zord = Postzord::Receiver.new(user, :object => @acceptance, :person => user2.person)
|
zord = Postzord::Receiver.new(user, :object => @acceptance, :person => user2.person)
|
||||||
zord.receive_object
|
zord.receive_object
|
||||||
end
|
end
|
||||||
|
|
|
||||||
5
spec/support/no_id_on_object.rb
Normal file
5
spec/support/no_id_on_object.rb
Normal file
|
|
@ -0,0 +1,5 @@
|
||||||
|
class Object
|
||||||
|
def id
|
||||||
|
raise "You have called id on a non-ActiveRecord object."
|
||||||
|
end
|
||||||
|
end
|
||||||
Loading…
Reference in a new issue