diff --git a/app/controllers/publics_controller.rb b/app/controllers/publics_controller.rb
index 3b555bd1e4733cd29f7718416614510ba4af939a..eb67146b3a451960d3bb1d67e1a6d69e240296d5 100644
--- a/app/controllers/publics_controller.rb
+++ b/app/controllers/publics_controller.rb
@@ -50,7 +50,7 @@ class PublicsController < ApplicationController
   end
 
   def receive_public
-    Postzord::Receiver::Public.new(params[:xml])
+    Resque.enqueue(Job::ReceivePublicSalmon, params[:xml])
     render :nothing => true, :status => :ok
   end
 
diff --git a/app/models/contact.rb b/app/models/contact.rb
index 00b6dde9f8e679af43d59b883d62cb0c9227a23e..e4e18fd62f3ea1af1830ccab056b8706d4754627 100644
--- a/app/models/contact.rb
+++ b/app/models/contact.rb
@@ -19,6 +19,8 @@ class Contact < ActiveRecord::Base
 
   validates_uniqueness_of :person_id, :scope => :user_id
 
+  before_destroy :destroy_notifications
+
   # contact.sharing is true when contact.person is sharing with contact.user
   scope :sharing, lambda {
     where(:sharing => true)
@@ -33,7 +35,6 @@ class Contact < ActiveRecord::Base
     sharing.where(:receiving => false)
   }
 
-  before_destroy :destroy_notifications
   def destroy_notifications
     Notification.where(:target_type => "Person",
                        :target_id => person_id,
diff --git a/app/models/job/receive_local_batch.rb b/app/models/job/receive_local_batch.rb
index d7e0801d6365697548da22998e36d293853a839e..f5689e797c1531928d88c5efe6be1619672e4ba6 100644
--- a/app/models/job/receive_local_batch.rb
+++ b/app/models/job/receive_local_batch.rb
@@ -2,56 +2,18 @@
 #   licensed under the Affero General Public License version 3 or later.  See
 #   the COPYRIGHT file.
 
+require File.join(Rails.root, 'lib/postzord/receiver')
+require File.join(Rails.root, 'lib/postzord/receiver/local_post_batch')
 
 module Job
   class ReceiveLocalBatch < Base
-    require File.join(Rails.root, 'lib/postzord/receiver')
 
     @queue = :receive
+
     def self.perform(post_id, recipient_user_ids)
       post = Post.find(post_id)
-      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)
-      contacts = Contact.where(:user_id => recipient_user_ids, :person_id => post.author_id)
-      
-      if postgres?
-        # Take the naive approach to inserting our new visibilities for now.
-        contacts.each do |contact|
-          PostVisibility.find_or_create_by_contact_id_and_post_id(contact.id, post.id)
-        end
-      else
-        # Use a batch insert on mySQL.
-        new_post_visibilities = contacts.map do |contact|
-          PostVisibility.new(:contact_id => contact.id, :post_id => post.id)
-        end
-        PostVisibility.import(new_post_visibilities)
-      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
+      receiver = Postzord::Receiver::LocalPostBatch.new(post, recipient_user_ids)
+      receiver.perform!
     end
   end
 end
diff --git a/app/models/job/receive_public_salmon.rb b/app/models/job/receive_public_salmon.rb
new file mode 100644
index 0000000000000000000000000000000000000000..d7f700576f8052dca32c1e3359f3819706b44c7c
--- /dev/null
+++ b/app/models/job/receive_public_salmon.rb
@@ -0,0 +1,17 @@
+#   Copyright (c) 2010, Diaspora Inc.  This file is
+#   licensed under the Affero General Public License version 3 or later.  See
+#   the COPYRIGHT file.
+
+
+module Job
+  class ReceivePublicSalmon < Base
+    require File.join(Rails.root, 'lib/postzord/receiver')
+
+    @queue = :receive
+
+    def self.perform(xml)
+      receiver = Postzord::Receiver::Public.new(xml)
+      receiver.perform!
+    end
+  end
+end
diff --git a/app/models/post_visibility.rb b/app/models/post_visibility.rb
index 69122f04672ffe81187dadf0a65b5be7842829ac..086eaa8bec3bc2af92c5ea6a5b5b76e5179cae1c 100644
--- a/app/models/post_visibility.rb
+++ b/app/models/post_visibility.rb
@@ -5,4 +5,20 @@
 class PostVisibility < ActiveRecord::Base
   belongs_to :contact
   belongs_to :post
+
+
+  def self.batch_import(contacts, post)
+    if postgres?
+      # Take the naive approach to inserting our new visibilities for now.
+      contacts.each do |contact|
+        PostVisibility.find_or_create_by_contact_id_and_post_id(contact.id, post.id)
+      end
+    else
+      # Use a batch insert on mySQL.
+      new_post_visibilities = contacts.map do |contact|
+        PostVisibility.new(:contact_id => contact.id, :post_id => post.id)
+      end
+      PostVisibility.import(new_post_visibilities)
+    end
+  end
 end
diff --git a/app/models/user.rb b/app/models/user.rb
index 3fc69e017df79fb5c5b8a81ccbc20c526649bd97..4b1e8684bbd042afe271b1845a4b0c1437ca1839 100644
--- a/app/models/user.rb
+++ b/app/models/user.rb
@@ -59,6 +59,10 @@ class User < ActiveRecord::Base
                   :invitation_identifier
 
 
+  def self.all_sharing_with_person(person)
+    User.joins(:contacts).where(:contacts => {:person_id => person.id})
+  end
+
   # @return [User]
   def self.find_by_invitation(invitation)
     service = invitation.service
diff --git a/lib/postzord/dispatch.rb b/lib/postzord/dispatch.rb
index 3b12e207a44ffcefc7af89cc7eee034536b02cc1..a04c65bdf3e7f700e1b3ef7e01ad06c3f46dc9b1 100644
--- a/lib/postzord/dispatch.rb
+++ b/lib/postzord/dispatch.rb
@@ -18,7 +18,7 @@ class Postzord::Dispatch
   end
 
   def salmon
-    @salmon_factory ||= Salmon::EncryptedSlap.create(@sender, @xml)
+    @salmon_factory ||= Salmon::EncryptedSlap.create_by_user_and_activity(@sender, @xml)
   end
 
   def post(opts = {})
diff --git a/lib/postzord/receiver.rb b/lib/postzord/receiver.rb
index f39efd4105f8fe78abb8d598d9f01bf7b0ba57f4..eb41080fe8b3df679a3b232187e909ee1afb0a3d 100644
--- a/lib/postzord/receiver.rb
+++ b/lib/postzord/receiver.rb
@@ -45,7 +45,7 @@ module Postzord
 
     protected
     def salmon
-      @salmon ||= Salmon::EncryptedSlap.parse(@salmon_xml, @user)
+      @salmon ||= Salmon::EncryptedSlap.from_xml(@salmon_xml, @user)
     end
 
     def xml_author
diff --git a/lib/postzord/receiver/local_post_batch.rb b/lib/postzord/receiver/local_post_batch.rb
new file mode 100644
index 0000000000000000000000000000000000000000..7c035a1426220402d999ad9028729a1d3b51604e
--- /dev/null
+++ b/lib/postzord/receiver/local_post_batch.rb
@@ -0,0 +1,45 @@
+module Postzord
+  class Receiver
+    class LocalPostBatch
+      attr_reader :post, :recipient_user_ids, :users
+
+      def initialize(post, recipient_user_ids)
+        @post = post
+        @recipient_user_ids = recipient_user_ids
+        @users = User.where(:id => @recipient_user_ids)
+      end
+
+      def perform!
+        create_visibilities
+        socket_to_users if @post.respond_to?(:socket_to_user)
+        notify_mentioned_users
+        notify_users
+      end
+
+      def create_visibilities
+        contacts = Contact.where(:user_id => @recipient_user_ids, :person_id => @post.author_id)
+        PostVisibility.batch_import(contacts, post)
+      end
+
+      def socket_to_users
+        @users.each do |user|
+          @post.socket_to_user(user)
+        end
+      end
+
+      def notify_mentioned_users
+        @post.mentions.each do |mention|
+          mention.notify_recipient
+        end
+      end
+
+      def notify_users
+        if @post.respond_to?(:notification_type) 
+          @users.each do |user|
+            Notification.notify(user, @post, @post.author)
+          end
+        end
+      end
+    end
+  end
+end
diff --git a/lib/postzord/receiver/public.rb b/lib/postzord/receiver/public.rb
index c2b6199ecc724885f90dce7edcbc40a14258376b..bc007ecf07e631203ba5eded64eb38a3d89dfcc2 100644
--- a/lib/postzord/receiver/public.rb
+++ b/lib/postzord/receiver/public.rb
@@ -5,12 +5,55 @@
 module Postzord
   class Receiver
     class Public
-      attr_accessor :xml
+      attr_accessor :salmon, :author
 
       def initialize(xml)
-        @xml = xml
-        
+        @salmon = Salmon::Slap.from_xml(xml) 
+        @author = Webfinger.new(@salmon.author_email).fetch
       end
+
+      # @return [Boolean]
+      def verified_signature?
+        @salmon.verified_for_key?(@author.public_key)
+      end
+
+      # @return [void]
+      def perform!
+        return false unless verified_signature?
+        return unless save_object
+
+        if @object.respond_to?(:relayable)
+          receive_relayable
+        else
+          Resque.enqueue(Job::ReceiveLocalBatch, @object.id, self.recipient_user_ids)
+        end
+      end
+
+      def receive_relayable
+        raise RelayableObjectWithoutParent.new("Receiving a relayable object without parent object present locally!") unless @object.parent.user.present?
+
+        # receive relayable object only for the owner of the parent object
+        @object.receive(@object.parent.user, @author)
+
+        # notify everyone who can see the parent object
+        receiver = Postzord::Receiver::LocalPostBatch.new(nil, self.recipient_user_ids)
+        receiver.notify_users
+      end
+
+      # @return [Object]
+      def save_object
+        @object = Diaspora::Parser::from_xml(@salmon.parsed_data)
+        raise "Object is not public" unless @object.public?
+        @object.save!
+      end
+
+      # @return [Array<Integer>] User ids
+      def recipient_user_ids
+        User.all_sharing_with_person(@author).select('users.id').map!{ |u| u.id }
+      end
+
+      class RelayableObjectWithoutParent < StandardError ; ; end
     end
   end
 end
+
diff --git a/lib/salmon/magic_sig_envelope.rb b/lib/salmon/magic_sig_envelope.rb
index ae93bdc3909a1a3ed8b468efbe6a7bc706fec919..063555b12cd4b0718f6a8b6adacb3e41ea436b3f 100644
--- a/lib/salmon/magic_sig_envelope.rb
+++ b/lib/salmon/magic_sig_envelope.rb
@@ -6,7 +6,6 @@ module Salmon
   class MagicSigEnvelope
     attr_accessor :data, :data_type, :encoding, :alg, :sig, :author
     def self.parse(doc)
-      puts doc.to_s
       env = self.new
       ns = {'me'=>'http://salmon-protocol.org/ns/magic-env'}
       env.encoding = doc.search('//me:env/me:encoding', ns).text.strip
diff --git a/spec/controllers/publics_controller_spec.rb b/spec/controllers/publics_controller_spec.rb
index 1616f09fc484aa9b4ff23dee26b1f15d1f78870a..5e48b0e74d4c814ef0cfdb42991c4c225c7b7cfe 100644
--- a/spec/controllers/publics_controller_spec.rb
+++ b/spec/controllers/publics_controller_spec.rb
@@ -31,9 +31,9 @@ describe PublicsController do
       response.code.should == '422'
     end
 
-    it 'calls Postzord::Receiver:Public' do
+    it 'enqueues a ReceivePublicSalmon job' do
       xml = "stuff"
-      Postzord::Receiver::Public.should_receive(:new).with(xml)
+      Resque.should_receive(:enqueue).with(Job::ReceivePublicSalmon, xml)
       post :receive_public, :xml => xml
     end
   end
@@ -57,7 +57,7 @@ describe PublicsController do
       xml2 = post1.to_diaspora_xml
       user2 = Factory(:user)
 
-      salmon_factory = Salmon::EncryptedSlap.create(@user, xml2)
+      salmon_factory = Salmon::EncryptedSlap.create_by_user_and_activity(@user, xml2)
       enc_xml = salmon_factory.xml_for(user2.person)
 
       Resque.should_receive(:enqueue).with(Job::ReceiveSalmon, @user.id, enc_xml).once
diff --git a/spec/lib/postzord/dispatch_spec.rb b/spec/lib/postzord/dispatch_spec.rb
index de6b1a60d1acb5445b4db48d89b8bfe39714fdaa..68a99eb335192c818c3fe78bcd0019824986ef19 100644
--- a/spec/lib/postzord/dispatch_spec.rb
+++ b/spec/lib/postzord/dispatch_spec.rb
@@ -231,7 +231,7 @@ describe Postzord::Dispatch do
 
       it 'calls salmon_for each remote person' do
        salmon = @mailman.salmon
-       Salmon::EncryptedSlap.stub(:create).and_return(salmon)
+       Salmon::EncryptedSlap.stub(:create_by_user_and_activity).and_return(salmon)
        salmon.should_receive(:xml_for).with(alice.person).and_return('what')
        @hydra.stub!(:queue)
        @hydra.stub!(:run)
diff --git a/spec/lib/postzord/receiver/local_post_batch_spec.rb b/spec/lib/postzord/receiver/local_post_batch_spec.rb
new file mode 100644
index 0000000000000000000000000000000000000000..89db17c836add165fc42134bb8f13086b8fba990
--- /dev/null
+++ b/spec/lib/postzord/receiver/local_post_batch_spec.rb
@@ -0,0 +1,93 @@
+require 'spec_helper' 
+require File.join(Rails.root, 'lib','postzord', 'receiver', 'local_post_batch')
+
+describe Postzord::Receiver::LocalPostBatch do
+  before do
+    @post = Factory(:status_message, :author => alice.person)
+    @ids = [bob.id] 
+
+    @receiver = Postzord::Receiver::LocalPostBatch.new(@post, @ids)
+  end
+
+  describe '.initialize' do
+    it 'sets @post, @recipient_user_ids, and @user' do
+      [:post, :recipient_user_ids, :users].each do |instance_var|
+        @receiver.send(instance_var).should_not be_nil
+      end
+    end
+  end
+
+  describe '#perform!' do
+    it 'calls .create_visibilities' do
+      @receiver.should_receive(:create_visibilities)
+      @receiver.perform!
+    end
+
+    it 'sockets to users' do
+      @receiver.should_receive(:socket_to_users)
+      @receiver.perform!
+    end
+
+    it 'notifies mentioned users' do
+      @receiver.should_receive(:notify_mentioned_users)
+      @receiver.perform!
+    end
+
+    it 'notifies users' do
+      @receiver.should_receive(:notify_users)
+      @receiver.perform!
+    end
+  end
+
+  describe '#create_visibilities' do
+    it 'calls Postvisibility.batch_import' do
+      PostVisibility.should_receive(:batch_import)
+      @receiver.create_visibilities
+    end
+  end
+
+  describe '#socket_to_users' do
+    before do
+      @controller = mock()
+      SocketsController.stub(:new).and_return(@controller)
+    end
+
+    it 'sockets to each user' do
+      @controller.should_receive(:outgoing).with(bob, @post, instance_of(Hash))
+      @receiver.socket_to_users
+    end
+  end
+
+  describe '#notify_mentioned_users' do
+    it 'calls notify person for a mentioned person' do
+      sm = Factory(:status_message,
+                   :author => alice.person,
+                   :text => "Hey @{Bob; #{bob.diaspora_handle}}")
+
+      receiver = Postzord::Receiver::LocalPostBatch.new(sm, @ids)
+      Notification.should_receive(:notify).with(bob, anything, alice.person)
+      receiver.notify_mentioned_users
+    end
+
+    it 'does not call notify person for a non-mentioned person' do
+      Notification.should_not_receive(:notify)
+      @receiver.notify_mentioned_users
+    end
+  end
+
+  describe '#notify_users' do
+    it 'calls notify for posts with notification type' do
+      reshare = Factory.create(:reshare)
+      Notification.should_receive(:notify)
+      receiver = Postzord::Receiver::LocalPostBatch.new(reshare, @ids)
+      receiver.notify_users
+    end
+
+    it 'calls notify for posts with notification type' do
+      sm = Factory.create(:status_message, :author => alice.person)
+      receiver = Postzord::Receiver::LocalPostBatch.new(sm, @ids)
+      Notification.should_not_receive(:notify)
+      receiver.notify_users
+    end
+  end
+end
diff --git a/spec/lib/postzord/receiver/public.rb b/spec/lib/postzord/receiver/public.rb
deleted file mode 100644
index 5b9259d09151c781610bc7829248ed62fb98e280..0000000000000000000000000000000000000000
--- a/spec/lib/postzord/receiver/public.rb
+++ /dev/null
@@ -1,32 +0,0 @@
-#   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'
-
-require File.join(Rails.root, 'lib/postzord')
-require File.join(Rails.root, 'lib/postzord/receiver/public')
-
-describe Postzord::Receiver::Public do
-
-  describe '#initialize' do
-
-  end
-
-  describe '#verify_signature' do
-
-  end
-
-  describe '#collect_recipients' do
-
-  end
-
-  describe '#batch_insert_visibilities' do
-
-  end
-
-  describe '#batch_notify' do
-
-  end
-
-end
diff --git a/spec/lib/postzord/receiver/public_spec.rb b/spec/lib/postzord/receiver/public_spec.rb
index 318cc1a023374621310a4024e82664b55b6f453c..7fab3872e2d7b2ae27574ecb6ef702b9fc38e43c 100644
--- a/spec/lib/postzord/receiver/public_spec.rb
+++ b/spec/lib/postzord/receiver/public_spec.rb
@@ -8,52 +8,60 @@ require File.join(Rails.root, 'lib/postzord')
 require File.join(Rails.root, 'lib/postzord/receiver/public')
 
 describe Postzord::Receiver::Public do
+  before do
+    @post = Factory.build(:status_message, :author => alice.person, :public => true)
+    @created_salmon = Salmon::Slap.create_by_user_and_activity(alice, @post.to_diaspora_xml)
+    @xml = @created_salmon.xml_for(nil)
+  end
 
   describe '#initialize' do
-    it 'sets xml as instance variable' do
-      receiver = Postzord::Receiver::Public.new("blah")
-      receiver.xml.should == 'blah'
+    it 'creates a Salmon instance variable' do
+      receiver = Postzord::Receiver::Public.new(@xml)
+      receiver.salmon.should_not be_nil
     end
   end
 
-  describe '#perform' do
-    it 'calls verify_signature' do
+  describe '#perform!' do
+    before do
+      @receiver = Postzord::Receiver::Public.new(@xml)
+    end
 
+    it 'calls verify_signature' do
+      @receiver.should_receive(:verified_signature?)
+      @receiver.perform!
     end
 
     context 'if signature is valid' do
-      it 'calls collect_recipients' do
-
+      it 'calls recipient_user_ids' do
+        @receiver.should_receive(:recipient_user_ids)
+        @receiver.perform!
       end
 
       it 'saves the parsed object' do
-
+        @receiver.should_receive(:save_object)
+        @receiver.perform!
       end
 
-      it 'calls batch_insert_visibilities' do
-
-      end
-
-      it 'calls batch_notify' do
-
+      it 'enqueues a Job::ReceiveLocalBatch' do 
+        Resque.should_receive(:enqueue).with(Job::ReceiveLocalBatch, anything, anything)
+        @receiver.perform!
       end
     end
   end
 
-  describe '#verify_signature' do
-
-  end
-
-  describe '#collect_recipients' do
-
-  end
-
-  describe '#batch_insert_visibilities' do
-
+  describe '#verify_signature?' do
+    it 'calls Slap#verified_for_key?' do
+      receiver = Postzord::Receiver::Public.new(@xml)
+      receiver.salmon.should_receive(:verified_for_key?).with(instance_of(OpenSSL::PKey::RSA))
+      receiver.verified_signature?
+    end
   end
 
-  describe '#batch_notify' do
-
+  describe '#recipient_user_ids' do
+    it 'calls User.all_sharing_with_person' do
+      User.should_receive(:all_sharing_with_person).and_return(stub(:select => []))
+      receiver = Postzord::Receiver::Public.new(@xml)
+      receiver.perform!
+    end
   end
-
 end
diff --git a/spec/lib/postzord/receiver_spec.rb b/spec/lib/postzord/receiver_spec.rb
index 434073fb4a9be69ce2617e7efb7f1aa390650aba..bcc5fe2040498db25a63519369b66bd1615ead09 100644
--- a/spec/lib/postzord/receiver_spec.rb
+++ b/spec/lib/postzord/receiver_spec.rb
@@ -24,7 +24,7 @@ describe Postzord::Receiver do
   describe '.initialize' do
     it 'valid for local' do
       Webfinger.should_not_receive(:new)
-      Salmon::EncryptedSlap.should_not_receive(:parse)
+      Salmon::EncryptedSlap.should_not_receive(:from_xml)
 
       zord = Postzord::Receiver.new(@user, :person => @person2, :object => @original_post)
       zord.instance_variable_get(:@user).should_not be_nil
@@ -37,7 +37,7 @@ describe Postzord::Receiver do
       web_mock = mock()
       web_mock.should_receive(:fetch).and_return true
       salmon_mock.should_receive(:author_email).and_return(true)
-      Salmon::EncryptedSlap.should_receive(:parse).with(@salmon_xml, @user).and_return(salmon_mock)
+      Salmon::EncryptedSlap.should_receive(:from_xml).with(@salmon_xml, @user).and_return(salmon_mock)
       Webfinger.should_receive(:new).and_return(web_mock)
 
       zord = Postzord::Receiver.new(@user, :salmon_xml => @salmon_xml)
diff --git a/spec/models/jobs/receive_local_batch_spec.rb b/spec/models/jobs/receive_local_batch_spec.rb
index a6eb038e0e6f71a3bb5e80aa0035e88185540367..5b9ba09f20673c458c218961074fa3c5ee2803b4 100644
--- a/spec/models/jobs/receive_local_batch_spec.rb
+++ b/spec/models/jobs/receive_local_batch_spec.rb
@@ -9,73 +9,10 @@ describe Job::ReceiveLocalBatch do
     @post = alice.build_post(:status_message, :text => 'Hey Bob')
     @post.save!
   end
-  describe '.perform' do
-    it 'calls .create_visibilities' do
-      Job::ReceiveLocalBatch.should_receive(:create_visibilities).with(@post, [bob.id])
-      Job::ReceiveLocalBatch.perform(@post.id, [bob.id])
-    end
-    it 'sockets to users' do
-      Job::ReceiveLocalBatch.should_receive(:socket_to_users).with(@post, [bob.id])
-      Job::ReceiveLocalBatch.perform(@post.id, [bob.id])
-    end
-    it 'notifies mentioned users' 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
-      PostVisibility.exists?(:contact_id => bob.contact_for(alice.person).id, :post_id => @post.id).should be_false
-      Job::ReceiveLocalBatch.create_visibilities(@post, [bob.id])
-      PostVisibility.exists?(:contact_id => bob.contact_for(alice.person).id, :post_id => @post.id).should be_true
-    end
-    it 'does not raise if a visibility already exists' do
-      PostVisibility.create!(:contact_id => bob.contact_for(alice.person).id, :post_id => @post.id)
-      lambda {
-        Job::ReceiveLocalBatch.create_visibilities(@post, [bob.id])
-      }.should_not raise_error
-    end
-  end
-  describe '.socket_to_users' do
-    before do
-      @controller = mock()
-      SocketsController.stub(:new).and_return(@controller)
-    end
-    it 'sockets to each user' do
-      @controller.should_receive(:outgoing).with(bob.id, @post, instance_of(Hash))
-      Job::ReceiveLocalBatch.socket_to_users(@post, [bob.id])
-    end
-  end
-  describe '.notify_mentioned_users' do
-    it 'calls notify person for a mentioned person' do
-      @post = alice.build_post(:status_message, :text => "Hey @{Bob; #{bob.diaspora_handle}}")
-      @post.save!
-      Notification.should_receive(:notify).with(bob, anything, alice.person)
-      Job::ReceiveLocalBatch.notify_mentioned_users(@post)
-    end
-    it 'does not call notify person for a non-mentioned person' do
-      Notification.should_not_receive(:notify)
-      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])
+  describe '.perform' do
+    it 'calls Postzord::Receiver::LocalPostBatch' do
+      pending
     end
   end
 end
diff --git a/spec/models/post_visibility_spec.rb b/spec/models/post_visibility_spec.rb
new file mode 100644
index 0000000000000000000000000000000000000000..29fc538a4a1f7e39feed87c97b17b8a76b9f8a93
--- /dev/null
+++ b/spec/models/post_visibility_spec.rb
@@ -0,0 +1,29 @@
+#   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 PostVisibility do
+  describe '.batch_import' do
+    before do
+      @post = Factory(:status_message, :author => alice.person)
+      @contact = bob.contact_for(alice.person)
+    end
+
+    it 'creates a visibility for each user' do
+      lambda {
+        PostVisibility.batch_import([@contact], @post)
+      }.should change {
+        PostVisibility.exists?(:contact_id => @contact.id, :post_id => @post.id)
+      }.from(false).to(true)
+    end
+
+    it 'does not raise if a visibility already exists' do
+      PostVisibility.create!(:contact_id => @contact.id, :post_id => @post.id)
+      lambda {
+        PostVisibility.batch_import([@contact], @post)
+      }.should_not raise_error
+    end
+  end
+end