fixed error with comments saving twice on the same pod

This commit is contained in:
zhitomirskiyi 2011-01-24 17:23:51 -08:00
parent 1b3c58c2c2
commit e9e01e965e
6 changed files with 81 additions and 56 deletions

View file

@ -61,26 +61,28 @@ class Comment < ActiveRecord::Base
end end
def receive(user, person) def receive(user, person)
commenter = self.person local_comment = Comment.where(:guid => self.guid).first
unless self.post.person == user.person || self.verify_post_creator_signature comment = local_comment || self
unless comment.post.person == user.person || comment.verify_post_creator_signature
Rails.logger.info("event=receive status=abort reason='comment signature not valid' recipient=#{user.diaspora_handle} sender=#{self.post.person.diaspora_handle} payload_type=#{self.class} post_id=#{self.post_id}") Rails.logger.info("event=receive status=abort reason='comment signature not valid' recipient=#{user.diaspora_handle} sender=#{self.post.person.diaspora_handle} payload_type=#{self.class} post_id=#{self.post_id}")
return return
end end
#sign comment as the post creator if you've been hit UPSTREAM #sign comment as the post creator if you've been hit UPSTREAM
if user.owns? self.post if user.owns? comment.post
self.post_creator_signature = self.sign_with_key(user.encryption_key) comment.post_creator_signature = comment.sign_with_key(user.encryption_key)
self.save comment.save
end end
#dispatch comment DOWNSTREAM, received it via UPSTREAM #dispatch comment DOWNSTREAM, received it via UPSTREAM
unless user.owns?(self) unless user.owns?(comment)
self.save comment.save
user.dispatch_comment(self) user.dispatch_comment(comment)
end end
self.socket_to_user(user, :aspect_ids => self.post.aspect_ids) comment.socket_to_user(user, :aspect_ids => comment.post.aspect_ids)
self comment
end end
#ENCRYPTION #ENCRYPTION

View file

@ -82,7 +82,7 @@ class Post < ActiveRecord::Base
else else
user.add_post_to_aspects(local_post) user.add_post_to_aspects(local_post)
Rails.logger.info("event=receive payload_type=#{self.class} update=true status=complete sender=#{self.diaspora_handle} existing_post=#{local_post.id}") Rails.logger.info("event=receive payload_type=#{self.class} update=true status=complete sender=#{self.diaspora_handle} existing_post=#{local_post.id}")
self local_post
end end
elsif !local_post elsif !local_post
self.save self.save

View file

@ -28,8 +28,8 @@ module Postzord
end end
def parse_and_receive(xml) def parse_and_receive(xml)
Rails.logger.info("event=receive status=start recipient=#{@user_person.diaspora_handle} payload_type=#{@object.class} sender=#{@sender.diaspora_handle}")
@object ||= Diaspora::Parser.from_xml(xml) @object ||= Diaspora::Parser.from_xml(xml)
Rails.logger.info("event=receive status=start recipient=#{@user_person.diaspora_handle} payload_type=#{@object.class} sender=#{@sender.diaspora_handle}")
if self.validate_object if self.validate_object
receive_object receive_object
end end
@ -37,8 +37,8 @@ module Postzord
def receive_object def receive_object
obj = @object.receive(@user, @author) obj = @object.receive(@user, @author)
Notification.notify(@user, @object, @author) if @object.respond_to?(:notification_type) Notification.notify(@user, obj, @author) if obj.respond_to?(:notification_type)
Rails.logger.info("event=receive status=complete recipient=#{@user_person.diaspora_handle} sender=#{@sender.diaspora_handle} payload_type#{@object.class}") Rails.logger.info("event=receive status=complete recipient=#{@user_person.diaspora_handle} sender=#{@sender.diaspora_handle} payload_type#{obj.class}")
obj obj
end end

View file

@ -31,7 +31,7 @@ class Webfinger
raise WebfingerFailedError.new(@account) raise WebfingerFailedError.new(@account)
end end
rescue rescue
Rails.logger.info("event=receive status=abort recipient=#{self.diaspora_handle} sender=#{salmon.author_email} reason='#{e.message}'") Rails.logger.info("event=receive status=abort recipient=#{@account} sender=#{salmon.author_email} reason='#{e.message}'")
nil nil
end end
end end

View file

@ -154,55 +154,77 @@ describe 'a user receives a post' do
end end
describe 'comments' do describe 'comments' do
before do
connect_users(@user1, @aspect, @user3, @aspect3)
@post = @user1.post :status_message, :message => "hello", :to => @aspect.id
xml = @post.to_diaspora_xml context 'remote' do
before do
connect_users(@user1, @aspect, @user3, @aspect3)
@post = @user1.post :status_message, :message => "hello", :to => @aspect.id
receive_with_zord(@user2, @user1.person, xml) xml = @post.to_diaspora_xml
receive_with_zord(@user3, @user1.person, xml)
@comment = @user3.comment('tada',:on => @post) receive_with_zord(@user2, @user1.person, xml)
@comment.post_creator_signature = @comment.sign_with_key(@user1.encryption_key) receive_with_zord(@user3, @user1.person, xml)
@xml = @comment.to_diaspora_xml
@comment.delete @comment = @user3.comment('tada',:on => @post)
@comment.post_creator_signature = @comment.sign_with_key(@user1.encryption_key)
@xml = @comment.to_diaspora_xml
@comment.delete
end
it 'should correctly attach the user already on the pod' do
@user2.reload.raw_visible_posts.size.should == 1
post_in_db = StatusMessage.find(@post.id)
post_in_db.comments.should == []
receive_with_zord(@user2, @user1.person, @xml)
post_in_db.comments(true).first.person.should == @user3.person
end
it 'should correctly marshal a stranger for the downstream user' do
remote_person = @user3.person.dup
@user3.person.delete
@user3.delete
remote_person.id = nil
#stubs async webfinger
Person.should_receive(:by_account_identifier).twice.and_return{ |handle|
if handle == @user1.person.diaspora_handle
@user1.person.save
@user1.person
else
remote_person.profile = Factory(:profile)
remote_person.save!
remote_person
end
}
@user2.reload.raw_visible_posts.size.should == 1
post_in_db = StatusMessage.find(@post.id)
post_in_db.comments.should == []
receive_with_zord(@user2, @user1.person, @xml)
post_in_db.comments(true).first.person.should == remote_person
end
end end
it 'should correctly attach the user already on the pod' do context 'local' do
@user2.reload.raw_visible_posts.size.should == 1 before do
post_in_db = StatusMessage.find(@post.id) @post = @user1.post :status_message, :message => "hello", :to => @aspect.id
post_in_db.comments.should == []
receive_with_zord(@user2, @user1.person, @xml)
post_in_db.comments(true).first.person.should == @user3.person xml = @post.to_diaspora_xml
end
it 'should correctly marshal a stranger for the downstream user' do receive_with_zord(@user2, @user1.person, xml)
remote_person = @user3.person.dup
@user3.person.delete
@user3.delete
remote_person.id = nil
#stubs async webfinger @comment = @user2.comment('tada',:on => @post)
Person.should_receive(:by_account_identifier).twice.and_return{ |handle| @xml = @comment.to_diaspora_xml
if handle == @user1.person.diaspora_handle end
@user1.person.save
@user1.person
else
remote_person.profile = Factory(:profile)
remote_person.save!
remote_person
end
}
@user2.reload.raw_visible_posts.size.should == 1 it 'does not raise a `Mysql2::Error: Duplicate entry...` exception on save' do
post_in_db = StatusMessage.find(@post.id) #lambda {
post_in_db.comments.should == [] receive_with_zord(@user1, @user2.person, @xml)
#}.should_not raise_exception
receive_with_zord(@user2, @user1.person, @xml) end
post_in_db.comments(true).first.person.should == remote_person
end end
end end

View file

@ -86,7 +86,8 @@ describe Postzord::Receiver do
it 'calls Notification.notify if object responds to notification_type' do it 'calls Notification.notify if object responds to notification_type' do
cm = Comment.new cm = Comment.new
cm.stub!(:receive) cm.stub!(:receive).and_return(cm)
Notification.should_receive(:notify).with(@user, cm, @person2) Notification.should_receive(:notify).with(@user, cm, @person2)
zord = Postzord::Receiver.new(@user, :person => @person2, :object => cm) zord = Postzord::Receiver.new(@user, :person => @person2, :object => cm)
zord.receive_object zord.receive_object