From cbdbe1b29ba411c0e3d0bc504a67cf669539bb79 Mon Sep 17 00:00:00 2001
From: danielgrippi <daniel@joindiaspora.com>
Date: Mon, 4 Apr 2011 19:22:19 -0700
Subject: [PATCH] follow wip.  2 failures.

---
 app/models/service_user.rb                  |   3 -
 app/views/services/_remote_friend.html.haml |   6 -
 lib/diaspora/user/connecting.rb             |  17 +-
 spec/controllers/aspects_controller_spec.rb |   2 +-
 spec/integration/receiving_spec.rb          | 173 +++++++-------
 spec/lib/postzord/dispatch_spec.rb          | 158 ++++++-------
 spec/models/aspect_spec.rb                  | 117 ----------
 spec/models/contact_spec.rb                 |  21 +-
 spec/models/person_spec.rb                  |  26 +--
 spec/models/retraction_spec.rb              |  35 +--
 spec/models/service_user_spec.rb            |  12 -
 spec/models/user/connecting_spec.rb         | 246 ++++----------------
 spec/models/user/invite_spec.rb             |  24 +-
 spec/models/user/posting_spec.rb            |  68 +++---
 spec/models/user/querying_spec.rb           |  21 +-
 spec/models/user_spec.rb                    | 135 +++++++----
 spec/spec_helper.rb                         |   5 +-
 17 files changed, 393 insertions(+), 676 deletions(-)

diff --git a/app/models/service_user.rb b/app/models/service_user.rb
index 2f1ce222ac..88408b9dc5 100644
--- a/app/models/service_user.rb
+++ b/app/models/service_user.rb
@@ -3,7 +3,6 @@ class ServiceUser < ActiveRecord::Base
   belongs_to :person
   belongs_to :contact
   belongs_to :service
-  belongs_to :request
   belongs_to :invitation
 
   before_save :attach_local_models
@@ -19,8 +18,6 @@ class ServiceUser < ActiveRecord::Base
 
     if self.person
       self.contact = self.service.user.contact_for(self.person)
-      self.request = Request.where(:recipient_id => self.service.user.person.id,
-                                   :sender_id => self.person_id).first
     end
 
     self.invitation = Invitation.joins(:recipient).where(:sender_id => self.service.user_id,
diff --git a/app/views/services/_remote_friend.html.haml b/app/views/services/_remote_friend.html.haml
index 65febe2c7d..cc37bb47d5 100644
--- a/app/views/services/_remote_friend.html.haml
+++ b/app/views/services/_remote_friend.html.haml
@@ -2,12 +2,6 @@
   .right
     -if friend.contact && !friend.contact.pending
       = t('people.person.already_connected')
-    - elsif (friend.contact && friend.contact.pending) || (friend.request && friend.request.sender_id != friend.person.id)
-      = t('people.person.pending_request')
-    - elsif (friend.request && friend.request.sender_id == friend.person.id)
-      = link_to t('people.show.incoming_request', :name => truncate(friend.person.name, :length => 20, :separator => ' ', :omission => '')),
-        '#',
-        :class => 'button'
     - elsif friend.invitation_id
       = t('invitations.new.already_invited')
       %br
diff --git a/lib/diaspora/user/connecting.rb b/lib/diaspora/user/connecting.rb
index 08961d30ca..3c5d25e8ea 100644
--- a/lib/diaspora/user/connecting.rb
+++ b/lib/diaspora/user/connecting.rb
@@ -13,10 +13,21 @@ module Diaspora
         end
         contact.aspects << aspect
         contact.save
+
+        if notification = Notification.where(:target_id => person.id).first
+          notification.update_attributes(:unread=>false)
+        end
+        
         contact
       end
 
-#begin
+
+      def receive_contact_request(request)
+        self.contacts.find_or_create_by_person_id(request.sender.id)
+        request
+      end
+
+=begin
       def send_contact_request_to(desired_contact, aspect)
         self.contacts.new(:person => desired_contact,
                           :pending => true)
@@ -90,7 +101,7 @@ module Diaspora
           :aspects => [aspect],
           :pending => false)
       end
-#end
+=end
 
       def disconnect(bad_contact)
         person = bad_contact.person
@@ -116,8 +127,6 @@ module Diaspora
         Rails.logger.info("event=disconnected_by user=#{diaspora_handle} target=#{person.diaspora_handle}")
         if contact = self.contact_for(person)
           remove_contact(contact)
-        elsif request = Request.where(:recipient_id => self.person.id, :sender_id => person.id).first
-          request.delete
         end
       end
 
diff --git a/spec/controllers/aspects_controller_spec.rb b/spec/controllers/aspects_controller_spec.rb
index 47fadafebc..8e5b0f10fe 100644
--- a/spec/controllers/aspects_controller_spec.rb
+++ b/spec/controllers/aspects_controller_spec.rb
@@ -238,7 +238,7 @@ describe AspectsController do
           aspect = @alice.aspects.create(:name => "aspect#{n}")
           8.times do |o|
             person = Factory(:person)
-            @alice.activate_contact(person, aspect)
+            @alice.contacts.create(:person => person, :aspects => [aspect])
           end
         end
         Benchmark.realtime{
diff --git a/spec/integration/receiving_spec.rb b/spec/integration/receiving_spec.rb
index e5ede524a9..8c0d4f22f3 100644
--- a/spec/integration/receiving_spec.rb
+++ b/spec/integration/receiving_spec.rb
@@ -12,48 +12,43 @@ describe 'a user receives a post' do
   end
 
   before do
-    @user1  = alice
-    @aspect = @user1.aspects.first
+    @aspect = alice.aspects.first
+    @aspect2 = bob.aspects.first
+    @aspect3 = eve.aspects.first
 
-    @user2   = bob
-    @aspect2 = @user2.aspects.first
-
-    @user3   = eve
-    @aspect3 = @user3.aspects.first
-
-    @contact = @user1.contact_for(@user2.person)
+    @contact = alice.contact_for(bob.person)
   end
 
   it 'streams only one message to the everyone aspect when a multi-aspected contacts posts' do
-    contact = @user1.contact_for(@user2.person)
-    @user1.add_contact_to_aspect(contact, @user1.aspects.create(:name => "villains"))
-    status = @user2.build_post(:status_message, :text => "Users do things", :to => @aspect2.id)
+    contact = alice.contact_for(bob.person)
+    alice.add_contact_to_aspect(contact, alice.aspects.create(:name => "villains"))
+    status = bob.build_post(:status_message, :text => "Users do things", :to => @aspect2.id)
     Diaspora::WebSocket.stub!(:is_connected?).and_return(true)
     Diaspora::WebSocket.should_receive(:queue_to_user).exactly(:once)
-    zord = Postzord::Receiver.new(@user1, :object => status, :person => @user2.person)
+    zord = Postzord::Receiver.new(alice, :object => status, :person => bob.person)
     zord.receive_object
   end
 
   it 'should be able to parse and store a status message from xml' do
-    status_message = @user2.post :status_message, :text => 'store this!', :to => @aspect2.id
+    status_message = bob.post :status_message, :text => 'store this!', :to => @aspect2.id
 
     xml = status_message.to_diaspora_xml
-    @user2.delete
+    bob.delete
     status_message.destroy
 
     lambda {
-      receive_with_zord(@user1, @user2.person, xml)
+      receive_with_zord(alice, bob.person, xml)
     }.should change(Post,:count).by(1)
   end
 
   it 'should not create new aspects on message receive' do
-    num_aspects = @user1.aspects.size
+    num_aspects = alice.aspects.size
 
     2.times do |n|
-      status_message = @user2.post :status_message, :text => "store this #{n}!", :to => @aspect2.id
+      status_message = bob.post :status_message, :text => "store this #{n}!", :to => @aspect2.id
     end
 
-    @user1.aspects.size.should == num_aspects
+    alice.aspects.size.should == num_aspects
   end
 
   it "should show bob's post to alice" do
@@ -71,66 +66,66 @@ describe 'a user receives a post' do
 
   context 'mentions' do
     it 'adds the notifications for the mentioned users regardless of the order they are received' do
-      Notification.should_receive(:notify).with(@user1, anything(), @user2.person)
-      Notification.should_receive(:notify).with(@user3, anything(), @user2.person)
+      Notification.should_receive(:notify).with(alice, anything(), bob.person)
+      Notification.should_receive(:notify).with(eve, anything(), bob.person)
 
-      @sm = @user2.build_post(:status_message, :text => "@{#{@user1.name}; #{@user1.diaspora_handle}} stuff @{#{@user3.name}; #{@user3.diaspora_handle}}")
+      @sm = bob.build_post(:status_message, :text => "@{#{alice.name}; #{alice.diaspora_handle}} stuff @{#{eve.name}; #{eve.diaspora_handle}}")
       @sm.stub!(:socket_to_user)
-      @user2.add_to_streams(@sm, [@user2.aspects.first])
+      bob.add_to_streams(@sm, [bob.aspects.first])
       @sm.save
 
-      zord = Postzord::Receiver.new(@user1, :object => @sm, :person => @user2.person)
+      zord = Postzord::Receiver.new(alice, :object => @sm, :person => bob.person)
       zord.receive_object
 
-      zord = Postzord::Receiver.new(@user3, :object => @sm, :person => @user2.person)
+      zord = Postzord::Receiver.new(eve, :object => @sm, :person => bob.person)
       zord.receive_object
     end
 
     it 'notifies users when receiving a mention in a post from a remote user' do
       @remote_person = Factory.create(:person, :diaspora_handle => "foobar@foobar.com")
-      Contact.create!(:user => @user1, :person => @remote_person, :aspects => [@aspect], :pending => false)
+      Contact.create!(:user => alice, :person => @remote_person, :aspects => [@aspect], :pending => false)
 
-      Notification.should_receive(:notify).with(@user1, anything(), @remote_person)
+      Notification.should_receive(:notify).with(alice, anything(), @remote_person)
 
-      @sm = Factory.build(:status_message, :text => "hello @{#{@user1.name}; #{@user1.diaspora_handle}}", :diaspora_handle => @remote_person.diaspora_handle, :author => @remote_person)
+      @sm = Factory.build(:status_message, :text => "hello @{#{alice.name}; #{alice.diaspora_handle}}", :diaspora_handle => @remote_person.diaspora_handle, :author => @remote_person)
       @sm.stub!(:socket_to_user)
       @sm.save
 
-      zord = Postzord::Receiver.new(@user1, :object => @sm, :person => @user2.person)
+      zord = Postzord::Receiver.new(alice, :object => @sm, :person => bob.person)
       zord.receive_object
     end
 
     it 'does not notify the mentioned user if the mentioned user is not friends with the post author' do
-      Notification.should_not_receive(:notify).with(@user1, anything(), @user3.person)
+      Notification.should_not_receive(:notify).with(alice, anything(), eve.person)
 
-      @sm = @user3.build_post(:status_message, :text => "should not notify @{#{@user1.name}; #{@user1.diaspora_handle}}")
+      @sm = eve.build_post(:status_message, :text => "should not notify @{#{alice.name}; #{alice.diaspora_handle}}")
       @sm.stub!(:socket_to_user)
-      @user3.add_to_streams(@sm, [@user3.aspects.first])
+      eve.add_to_streams(@sm, [eve.aspects.first])
       @sm.save
 
-      zord = Postzord::Receiver.new(@user1, :object => @sm, :person => @user2.person)
+      zord = Postzord::Receiver.new(alice, :object => @sm, :person => bob.person)
       zord.receive_object
     end
   end
 
   context 'update posts' do
     it 'does not update posts not marked as mutable' do
-      status = @user1.post :status_message, :text => "store this!", :to => @aspect.id
+      status = alice.post :status_message, :text => "store this!", :to => @aspect.id
       status.text = 'foo'
       xml = status.to_diaspora_xml
 
-      receive_with_zord(@user2, @user1.person, xml)
+      receive_with_zord(bob, alice.person, xml)
 
       status.reload.text.should == 'store this!'
     end
 
     it 'updates posts marked as mutable' do
-      photo = @user1.post(:photo, :user_file => uploaded_photo, :text => "Original", :to => @aspect.id)
+      photo = alice.post(:photo, :user_file => uploaded_photo, :text => "Original", :to => @aspect.id)
       photo.text = 'foo'
       xml = photo.to_diaspora_xml
-      @user2.reload
+      bob.reload
 
-      receive_with_zord(@user2, @user1.person, xml)
+      receive_with_zord(bob, alice.person, xml)
 
       photo.reload.text.should match(/foo/)
     end
@@ -151,31 +146,32 @@ describe 'a user receives a post' do
 
   describe 'post refs' do
     before do
-      @status_message = @user2.post :status_message, :text => "hi", :to => @aspect2.id
-      @user1.reload
+      @status_message = bob.post(:status_message, :text => "hi", :to => @aspect2.id)
+      alice.reload
       @aspect.reload
-      @contact = @user1.contact_for(@user2.person)
+      @contact = alice.contact_for(bob.person)
     end
 
     it "adds a received post to the the contact" do
-      @user1.raw_visible_posts.include?(@status_message).should be_true
+      alice.raw_visible_posts.include?(@status_message).should be_true
       @contact.posts.include?(@status_message).should be_true
     end
 
     it 'removes posts upon disconnecting' do
-      @user1.disconnect(@contact)
-      @user1.reload
-      @user1.raw_visible_posts.should_not include @status_message
+      alice.disconnect(@contact)
+      alice.reload
+      alice.raw_visible_posts.should_not include @status_message
     end
 
     context 'dependant delete' do
       before do
         @person = Factory(:person)
-        @user1.activate_contact(@person, @aspect)
+        alice.contacts.create(:person => @person, :aspects => [@aspect])
+
         @post = Factory.create(:status_message, :author => @person)
         @post.post_visibilities.should be_empty
-        receive_with_zord(@user1, @person, @post.to_diaspora_xml)
-        @contact = @user1.contact_for(@person)
+        receive_with_zord(alice, @person, @post.to_diaspora_xml)
+        @contact = alice.contact_for(@person)
         @contact.post_visibilities.reset
         @contact.posts(true).should include(@post)
         @post.post_visibilities.reset
@@ -183,13 +179,13 @@ describe 'a user receives a post' do
 
       it 'deletes a post if the noone links to it' do
         lambda {
-          @user1.disconnected_by(@person)
+          alice.disconnected_by(@person)
         }.should change(Post, :count).by(-1)
       end
 
       it 'deletes post_visibilities on disconnected by' do
         lambda {
-          @user1.disconnected_by(@person)
+          alice.disconnected_by(@person)
         }.should change{@post.post_visibilities(true).count}.by(-1)
       end
     end
@@ -198,7 +194,7 @@ describe 'a user receives a post' do
       @status_message.user_refs.should == 3
       @status_message.contacts(true).should include(@contact)
 
-      @user1.disconnect(@contact)
+      alice.disconnect(@contact)
       @status_message.reload
       @status_message.contacts(true).should_not include(@contact)
       @status_message.post_visibilities.reset
@@ -210,15 +206,15 @@ describe 'a user receives a post' do
       @status_message.post_visibilities.reset
       @status_message.user_refs.should == 3
 
-      new_user.activate_contact(@user2.person, new_user.aspects.first)
+      new_user.contacts.create(:person => bob.person, :aspects => [new_user.aspects.first])
       xml = @status_message.to_diaspora_xml
 
-      receive_with_zord(new_user, @user2.person, xml)
+      receive_with_zord(new_user, bob.person, xml)
 
       @status_message.post_visibilities.reset
       @status_message.user_refs.should == 4
 
-      @user1.disconnect(@contact)
+      alice.disconnect(@contact)
       @status_message.post_visibilities.reset
       @status_message.user_refs.should == 3
     end
@@ -228,41 +224,41 @@ describe 'a user receives a post' do
 
     context 'remote' do
       before do
-        connect_users(@user1, @aspect, @user3, @aspect3)
-        @post = @user1.post :status_message, :text => "hello", :to => @aspect.id
+        connect_users(alice, @aspect, eve, @aspect3)
+        @post = alice.post(:status_message, :text => "hello", :to => @aspect.id)
 
         xml = @post.to_diaspora_xml
 
-        receive_with_zord(@user2, @user1.person, xml)
-        receive_with_zord(@user3, @user1.person, xml)
+        receive_with_zord(bob, alice.person, xml)
+        receive_with_zord(eve, alice.person, xml)
 
-        @comment = @user3.comment('tada',:on => @post)
-        @comment.parent_author_signature = @comment.sign_with_key(@user1.encryption_key)
+        @comment = eve.comment('tada',:on => @post)
+        @comment.parent_author_signature = @comment.sign_with_key(alice.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
+        bob.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)
+        receive_with_zord(bob, alice.person, @xml)
 
-        post_in_db.comments(true).first.author.should == @user3.person
+        post_in_db.comments(true).first.author.should == eve.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 = eve.person.dup
+        eve.person.delete
+        eve.delete
         Person.where(:id => remote_person.id).delete_all
         Profile.where(:person_id => remote_person.id).delete_all
         remote_person.id = nil
 
         Person.should_receive(:by_account_identifier).twice.and_return{ |handle|
-          if handle == @user1.person.diaspora_handle
-            @user1.person.save
-            @user1.person
+          if handle == alice.person.diaspora_handle
+            alice.person.save
+            alice.person
           else
             remote_person.save(:validate => false)
             remote_person.profile = Factory(:profile, :person => remote_person)
@@ -270,11 +266,11 @@ describe 'a user receives a post' do
           end
         }
 
-        @user2.reload.raw_visible_posts.size.should == 1
+        bob.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)
+        receive_with_zord(bob, alice.person, @xml)
 
         post_in_db.comments(true).first.author.should == remote_person
       end
@@ -282,20 +278,20 @@ describe 'a user receives a post' do
 
     context 'local' do
       before do
-        @post = @user1.post :status_message, :text => "hello", :to => @aspect.id
+        @post = alice.post :status_message, :text => "hello", :to => @aspect.id
 
         xml = @post.to_diaspora_xml
 
-        receive_with_zord(@user2, @user1.person, xml)
-        receive_with_zord(@user3, @user1.person, xml)
+        receive_with_zord(bob, alice.person, xml)
+        receive_with_zord(eve, alice.person, xml)
       end
 
       it 'does not raise a `Mysql2::Error: Duplicate entry...` exception on save' do
-        @comment = @user2.comment('tada',:on => @post)
+        @comment = bob.comment('tada',:on => @post)
         @xml = @comment.to_diaspora_xml
 
         lambda {
-            receive_with_zord(@user1, @user2.person, @xml)
+            receive_with_zord(alice, bob.person, @xml)
         }.should_not raise_exception
       end
     end
@@ -312,8 +308,7 @@ describe 'a user receives a post' do
       @post = Factory.build(:status_message, :text => 'hey', :guid => 12313123, :author=> @remote_raphael, :created_at => 5.days.ago, :updated_at => 5.days.ago)
       xml = @post.to_diaspora_xml
       receive_with_zord(@local_luke, @remote_raphael, xml)
-      sleep(2)
-      old_time = Time.now
+      old_time = Time.now+1
       receive_with_zord(@local_leia, @remote_raphael, xml)
       (Post.find_by_guid @post.guid).updated_at.should be < old_time
       (Post.find_by_guid @post.guid).created_at.should be < old_time
@@ -332,38 +327,38 @@ describe 'a user receives a post' do
 
 
   describe 'salmon' do
-    let(:post){@user1.post :status_message, :text => "hello", :to => @aspect.id}
-    let(:salmon){@user1.salmon( post )}
+    let(:post){alice.post :status_message, :text => "hello", :to => @aspect.id}
+    let(:salmon){alice.salmon( post )}
 
     it 'processes a salmon for a post' do
-      salmon_xml = salmon.xml_for(@user2.person)
+      salmon_xml = salmon.xml_for(bob.person)
 
-      zord = Postzord::Receiver.new(@user2, :salmon_xml => salmon_xml)
+      zord = Postzord::Receiver.new(bob, :salmon_xml => salmon_xml)
       zord.perform
 
-      @user2.raw_visible_posts.include?(post).should be_true
+      bob.raw_visible_posts.include?(post).should be_true
     end
   end
 
 
   context 'retractions' do
     it 'should accept retractions' do
-      message = @user2.post(:status_message, :text => "cats", :to => @aspect2.id)
+      message = bob.post(:status_message, :text => "cats", :to => @aspect2.id)
       retraction = Retraction.for(message)
       xml = retraction.to_diaspora_xml
 
       lambda {
-        zord = Postzord::Receiver.new(@user1, :person => @user2.person)
+        zord = Postzord::Receiver.new(alice, :person => bob.person)
         zord.parse_and_receive(xml)
       }.should change(StatusMessage, :count).by(-1)
     end
 
     it 'should process retraction for a person' do
-      retraction = Retraction.for(@user2)
+      retraction = Retraction.for(bob)
       retraction_xml = retraction.to_diaspora_xml
 
       lambda {
-        zord = Postzord::Receiver.new(@user1, :person => @user2.person)
+        zord = Postzord::Receiver.new(alice, :person => bob.person)
         zord.parse_and_receive(retraction_xml)
       }.should change {
         @aspect.contacts(true).size }.by(-1)
@@ -373,7 +368,7 @@ describe 'a user receives a post' do
 
   it 'should marshal a profile for a person' do
     #Create person
-    person = @user2.person
+    person = bob.person
     id = person.id
     person.profile.delete
     person.profile = Profile.new(:first_name => 'bob', :last_name => 'billytown', :image_url => "http://clown.com", :person_id => person.id)
@@ -387,7 +382,7 @@ describe 'a user receives a post' do
     xml = new_profile.to_diaspora_xml
 
     #Marshal profile
-    zord = Postzord::Receiver.new(@user1, :person => person)
+    zord = Postzord::Receiver.new(alice, :person => person)
     zord.parse_and_receive(xml)
 
     #Check that marshaled profile is the same as old profile
diff --git a/spec/lib/postzord/dispatch_spec.rb b/spec/lib/postzord/dispatch_spec.rb
index 345396c280..d1e4fae54d 100644
--- a/spec/lib/postzord/dispatch_spec.rb
+++ b/spec/lib/postzord/dispatch_spec.rb
@@ -71,99 +71,52 @@ describe Postzord::Dispatch do
         @zord.should_receive(:deliver_to_remote).with(@remote_people)
         @zord.post
       end
+    end
+
+    context "comments" do
+      before do
+        @local_luke, @local_leia, @remote_raphael = set_up_friends
+      end
 
-      context "comments" do
+      context "local luke's post is commented on by" do
         before do
-          @local_luke, @local_leia, @remote_raphael = set_up_friends
+          @post = @local_luke.post(:status_message, :text => "hello", :to => @local_luke.aspects.first)
         end
-
-        context "local luke's post is commented on by" do
+        context "local leia" do
           before do
-            @post = @local_luke.post(:status_message, :text => "hello", :to => @local_luke.aspects.first)
-          end
-          context "local leia" do
-            before do
-              @comment = @local_leia.build_comment "yo", :on => @post
-              @comment.save
-            end
-            context "local leia's mailman" do
-              before do
-                @mailman = Postzord::Dispatch.new(@local_leia, @comment)
-              end
-              it 'calls deliver_to_local with local_luke' do
-                @mailman.should_receive(:deliver_to_local).with([@local_luke.person])
-                @mailman.post
-              end
-              it 'calls deliver_to_remote with nobody' do
-                @mailman.should_receive(:deliver_to_remote).with([])
-                @mailman.post
-              end
-              it 'does not call socket_to_users' do
-                @mailman.should_not_receive(:socket_to_users)
-                @mailman.post
-              end
-              it 'does not call notify_users' do
-                @mailman.should_not_receive(:notify_users)
-                @mailman.post
-              end
-            end
-            context "local luke's mailman" do
-              before do
-                @mailman = Postzord::Dispatch.new(@local_luke, @comment)
-              end
-              it 'does not call deliver_to_local' do
-                @mailman.should_not_receive(:deliver_to_local)
-                @mailman.post
-              end
-              it 'calls deliver_to_remote with remote raphael' do
-                @mailman.should_receive(:deliver_to_remote).with([@remote_raphael])
-                @mailman.post
-              end
-              it 'calls socket_to_users' do
-                @mailman.should_receive(:socket_to_users).with([@local_leia, @local_luke])
-                @mailman.post
-              end
-              it 'calls notify_users' do
-                @mailman.should_receive(:notify_users).with([@local_leia])
-                @mailman.post
-              end
-            end
-
+            @comment = @local_leia.build_comment "yo", :on => @post
+            @comment.save
           end
-          context "remote raphael" do
+          context "local leia's mailman" do
             before do
-              @comment = Factory.build(:comment, :author => @remote_raphael, :post => @post)
-              @comment.save
-              @mailman = Postzord::Dispatch.new(@local_luke, @comment)
+              @mailman = Postzord::Dispatch.new(@local_leia, @comment)
             end
-            it 'does not call deliver_to_local' do
-              @mailman.should_not_receive(:deliver_to_local)
+            it 'calls deliver_to_local with local_luke' do
+              @mailman.should_receive(:deliver_to_local).with([@local_luke.person])
               @mailman.post
             end
-            it 'calls deliver_to_remote with remote_raphael' do
-              @mailman.should_receive(:deliver_to_remote).with([@remote_raphael])
+            it 'calls deliver_to_remote with nobody' do
+              @mailman.should_receive(:deliver_to_remote).with([])
               @mailman.post
             end
-            it 'calls socket_to_users' do
-              @mailman.should_receive(:socket_to_users).with([@local_leia])
+            it 'does not call socket_to_users' do
+              @mailman.should_not_receive(:socket_to_users)
               @mailman.post
             end
-            it 'calls notify_users' do
-              @mailman.should_receive(:notify_users).with([@local_leia])
+            it 'does not call notify_users' do
+              @mailman.should_not_receive(:notify_users)
               @mailman.post
             end
           end
-          context "local luke" do
+          context "local luke's mailman" do
             before do
-              @comment = @local_luke.build_comment "yo", :on => @post
-              @comment.save
               @mailman = Postzord::Dispatch.new(@local_luke, @comment)
             end
             it 'does not call deliver_to_local' do
               @mailman.should_not_receive(:deliver_to_local)
               @mailman.post
             end
-            it 'calls deliver_to_remote with remote_raphael' do
+            it 'calls deliver_to_remote with remote raphael' do
               @mailman.should_receive(:deliver_to_remote).with([@remote_raphael])
               @mailman.post
             end
@@ -176,31 +129,78 @@ describe Postzord::Dispatch do
               @mailman.post
             end
           end
+
         end
-        context "remote raphael's post is commented on by local luke" do
+        context "remote raphael" do
           before do
-            @post = Factory(:status_message, :author => @remote_raphael)
-            @comment = @local_luke.build_comment "yo", :on => @post
+            @comment = Factory.build(:comment, :author => @remote_raphael, :post => @post)
             @comment.save
             @mailman = Postzord::Dispatch.new(@local_luke, @comment)
           end
+          it 'does not call deliver_to_local' do
+            @mailman.should_not_receive(:deliver_to_local)
+            @mailman.post
+          end
           it 'calls deliver_to_remote with remote_raphael' do
             @mailman.should_receive(:deliver_to_remote).with([@remote_raphael])
             @mailman.post
           end
-          it 'calls deliver_to_local with nobody' do
-            @mailman.should_receive(:deliver_to_local).with([])
+          it 'calls socket_to_users' do
+            @mailman.should_receive(:socket_to_users).with([@local_leia])
+            @mailman.post
+          end
+          it 'calls notify_users' do
+            @mailman.should_receive(:notify_users).with([@local_leia])
+            @mailman.post
+          end
+        end
+        context "local luke" do
+          before do
+            @comment = @local_luke.build_comment "yo", :on => @post
+            @comment.save
+            @mailman = Postzord::Dispatch.new(@local_luke, @comment)
+          end
+          it 'does not call deliver_to_local' do
+            @mailman.should_not_receive(:deliver_to_local)
+            @mailman.post
+          end
+          it 'calls deliver_to_remote with remote_raphael' do
+            @mailman.should_receive(:deliver_to_remote).with([@remote_raphael])
             @mailman.post
           end
-          it 'does not call socket_to_users' do
-            @mailman.should_not_receive(:socket_to_users)
+          it 'calls socket_to_users' do
+            @mailman.should_receive(:socket_to_users).with([@local_leia, @local_luke])
             @mailman.post
           end
-          it 'does not call notify_users' do
-            @mailman.should_not_receive(:notify_users)
+          it 'calls notify_users' do
+            @mailman.should_receive(:notify_users).with([@local_leia])
             @mailman.post
           end
+        end
+      end
 
+      context "remote raphael's post is commented on by local luke" do
+        before do
+          @post = Factory(:status_message, :author => @remote_raphael)
+          @comment = @local_luke.build_comment "yo", :on => @post
+          @comment.save
+          @mailman = Postzord::Dispatch.new(@local_luke, @comment)
+        end
+        it 'calls deliver_to_remote with remote_raphael' do
+          @mailman.should_receive(:deliver_to_remote).with([@remote_raphael])
+          @mailman.post
+        end
+        it 'calls deliver_to_local with nobody' do
+          @mailman.should_receive(:deliver_to_local).with([])
+          @mailman.post
+        end
+        it 'does not call socket_to_users' do
+          @mailman.should_not_receive(:socket_to_users)
+          @mailman.post
+        end
+        it 'does not call notify_users' do
+          @mailman.should_not_receive(:notify_users)
+          @mailman.post
         end
       end
     end
diff --git a/spec/models/aspect_spec.rb b/spec/models/aspect_spec.rb
index b0acb9455d..66377aaed5 100644
--- a/spec/models/aspect_spec.rb
+++ b/spec/models/aspect_spec.rb
@@ -18,9 +18,6 @@ describe Aspect do
 
   describe 'creation' do
     let!(:aspect){user.aspects.create(:name => 'losers')}
-    it 'has a name' do
-      aspect.name.should == "losers"
-    end
 
     it 'does not allow duplicate names' do
       lambda {
@@ -46,14 +43,6 @@ describe Aspect do
       aspect.contacts.size.should == 1
     end
 
-    it 'is able to have users and people and contacts' do
-      contact1 = Contact.create(:user => user, :person => user2.person, :aspects => [aspect])
-      contact2 = Contact.create(:user => user, :person => connected_person_2, :aspects => [aspect])
-      aspect.contacts.include?(contact1).should be_true
-      aspect.contacts.include?(contact2).should be_true
-      aspect.save.should be_true
-    end
-
     it 'has a contacts_visible? method' do
       aspect.contacts_visible?.should be_true
     end
@@ -71,110 +60,4 @@ describe Aspect do
       aspect2.should be_valid
     end
   end
-
-  describe 'querying' do
-    before do
-      aspect
-      user.activate_contact(connected_person, aspect)
-    end
-
-    it 'belong to a user' do
-      aspect.user.id.should == user.id
-      user.aspects.should == [aspect]
-    end
-
-    it 'should have contacts' do
-      aspect.contacts.size.should == 2
-    end
-
-    describe '#aspects_with_person' do
-      let!(:aspect_without_contact) {user.aspects.create(:name => "Another aspect")}
-      it 'should return the aspects with given contact' do
-        user.reload
-        aspects = user.aspects_with_person(connected_person)
-        aspects.size.should == 1
-        aspects.first.should == aspect
-      end
-
-      it 'returns multiple aspects if the person is there' do
-        user.reload
-        contact = user.contact_for(connected_person)
-        user.add_contact_to_aspect(contact, aspect1)
-        aspects = user.aspects_with_person(connected_person)
-        aspects.count.should == 2
-        aspects.each{ |asp| asp.contacts.include?(contact).should be_true }
-        aspects.include?(aspect_without_contact).should be_false
-      end
-    end
-  end
-
-  describe 'posting' do
-
-    it 'should add post to aspect via post method' do
-      aspect = user.aspects.create(:name => 'losers')
-      contact = aspect.contacts.create(:person => connected_person)
-
-      status_message = user.post(:status_message, :text => "hey", :to => aspect.id)
-
-      aspect.reload
-      aspect.posts.include?(status_message).should be true
-    end
-
-  end
-
-  context "aspect management" do
-    before do
-      connect_users(user, aspect, user2, aspect2)
-      aspect.reload
-      user.reload
-      @contact = user.contact_for(user2.person)
-    end
-
-
-    describe "#add_contact_to_aspect" do
-      it 'adds the contact to the aspect' do
-        aspect1.contacts.include?(@contact).should be_false
-        user.add_contact_to_aspect(@contact, aspect1)
-        aspect1.reload
-        aspect1.contacts.include?(@contact).should be_true
-      end
-
-      it 'returns true if they are already in the aspect' do
-        user.add_contact_to_aspect(@contact, aspect).should == true
-      end
-    end
-    context 'moving and removing posts' do
-      before do
-        @message  = user2.post(:status_message, :text => "Hey Dude", :to => aspect2.id)
-        aspect.reload
-        user.reload
-      end
-
-      describe 'User#move_contact' do
-        it 'should be able to move a contact from one of users existing aspects to another' do
-          user.move_contact(user2.person, aspect1, aspect)
-
-          aspect.contacts(true).include?(@contact).should be_false
-          aspect1.contacts(true).include?(@contact).should be_true
-        end
-
-        it "should not move a person who is not a contact" do
-          proc{
-            user.move_contact(connected_person, aspect1, aspect)
-          }.should raise_error
-
-          aspect.reload
-          aspect1.reload
-          aspect.contacts.where(:person_id => connected_person.id).should be_empty
-          aspect1.contacts.where(:person_id => connected_person.id).should be_empty
-        end
-
-        it 'does not try to delete if add person did not go through' do
-          user.should_receive(:add_contact_to_aspect).and_return(false)
-          user.should_not_receive(:delete_person_from_aspect)
-          user.move_contact(user2.person, aspect1, aspect)
-        end
-      end
-    end
-  end
 end
diff --git a/spec/models/contact_spec.rb b/spec/models/contact_spec.rb
index 7be737802c..f2829765fa 100644
--- a/spec/models/contact_spec.rb
+++ b/spec/models/contact_spec.rb
@@ -31,29 +31,20 @@ describe Contact do
     end
 
     it 'ensures user is not making a contact for himself' do
-      user = Factory.create(:user)
-
-      contact.person = user.person
-      contact.user = user
+      contact.person = alice.person
+      contact.user = alice
 
       contact.valid?
       contact.errors.full_messages.should include "Cannot create self-contact"
     end
 
-    it 'has many aspects' do
-      contact.aspects.should be_empty
-    end
-
     it 'validates uniqueness' do
-      user = Factory.create(:user)
       person = Factory(:person)
 
-      contact2 = Contact.create(:user => user,
-                                :person => person)
-
+      contact2 = alice.contacts.create(:person=>person)
       contact2.should be_valid
 
-      contact.user = user
+      contact.user = alice
       contact.person = person
       contact.should_not be_valid
     end
@@ -70,12 +61,12 @@ describe Contact do
 
       1.upto(5) do
         person = Factory(:person)
-        bob.activate_contact(person, bob.aspects.first)
+        bob.contacts.create(:person => person, :aspects => [bob.aspects.first])
         @people1 << person
       end
       1.upto(5) do
         person = Factory(:person)
-        bob.activate_contact(person, bob.aspects.last)
+        bob.contacts.create(:person => person, :aspects => [bob.aspects.last])
         @people2 << person
       end
     #eve <-> bob <-> alice
diff --git a/spec/models/person_spec.rb b/spec/models/person_spec.rb
index dbad049abc..64ffb55af7 100644
--- a/spec/models/person_spec.rb
+++ b/spec/models/person_spec.rb
@@ -128,7 +128,7 @@ describe Person do
     end
 
     it "deletes all contacts pointing towards a person" do
-      @user.activate_contact(@deleter, @user.aspects.first)
+      @user.contacts.create(:person => @deleter, :aspects => [@user.aspects.first])
       @deleter.destroy
       @user.contact_for(@deleter).should be_nil
     end
@@ -143,22 +143,6 @@ describe Person do
       }.should change(Profile, :count).by(-1)
     end
 
-    it 'deletes all requests to a person' do
-      alice.send_contact_request_to(eve.person, alice.aspects.first)
-      Request.count.should == 1
-      lambda {
-        eve.person.destroy
-      }.should change(Request, :count).by(-1)
-    end
-
-    it 'deletes all requests from a person' do
-      Request.create(:sender_id => @deleter.id, :recipient_id => alice.person.id)
-      Request.count.should == 1
-      lambda {
-        @deleter.destroy
-      }.should change(Request, :count).by(-1)
-    end
-
     it "deletes a person's comments on person deletion" do
       Factory.create(:comment, :author_id => @deleter.id, :diaspora_handle => @deleter.diaspora_handle, :text => "i love you",     :post => @other_status)
       Factory.create(:comment, :author_id => @person.id,:diaspora_handle => @person.diaspora_handle,  :text => "you are creepy", :post => @other_status)
@@ -174,14 +158,14 @@ describe Person do
       @aspect2 = @user2.aspects.create(:name => "Abscence of Babes")
     end
     it 'should not delete an orphaned contact' do
-      @user.activate_contact(@person, @aspect)
+      @user.contacts.create(:person => @person, :aspects => [@aspect])
 
       lambda {@user.disconnect(@user.contact_for(@person))}.should_not change(Person, :count)
     end
 
     it 'should not delete an un-orphaned contact' do
-      @user.activate_contact(@person, @aspect)
-      @user2.activate_contact(@person, @aspect2)
+      @user.contacts.create(:person => @person, :aspects => [@aspect])
+      @user2.contacts.create(:person => @person, :aspects => [@aspect2])
 
       lambda {@user.disconnect(@user.contact_for(@person))}.should_not change(Person, :count)
     end
@@ -293,7 +277,7 @@ describe Person do
       @casey_grippi.profile.first_name = "AAA"
       @casey_grippi.profile.save
 
-      @user.activate_contact(@casey_grippi, @user.aspects.first)
+      @user.contacts.create(:person => @casey_grippi, :aspects => [@user.aspects.first])
 
       people = Person.search("AAA", @user)
       people.map{|p| p.name}.should == [@casey_grippi, @yevgeniy_dodis, @robert_grimm, @eugene_weinstein].map{|p|p.name}
diff --git a/spec/models/retraction_spec.rb b/spec/models/retraction_spec.rb
index 6f0a648f3d..6aee4a0741 100644
--- a/spec/models/retraction_spec.rb
+++ b/spec/models/retraction_spec.rb
@@ -5,42 +5,43 @@
 require 'spec_helper'
 
 describe Retraction do
-
-  let(:user) { alice }
-  let(:person) { Factory(:person) }
-  let(:aspect) { user.aspects.create(:name => "Bruisers") }
-  let!(:activation) { user.activate_contact(person, aspect) }
-  let!(:post) { user.post :status_message, :text => "Destroy!", :to => aspect.id }
+  before do
+    @aspect = alice.aspects.first
+    alice.contacts.create(:person => eve.person, :aspects => [@aspect])
+    @post = alice.post :status_message, :text => "Destroy!", :to => @aspect.id
+  end
 
   describe 'serialization' do
     it 'should have a post id after serialization' do
-      retraction = Retraction.for(post)
+      retraction = Retraction.for(@post)
       xml = retraction.to_xml.to_s
-      xml.include?(post.guid.to_s).should == true
+      xml.include?(@post.guid.to_s).should == true
     end
   end
 
   describe '#subscribers' do
     it 'returns the subscribers to the post for all objects other than person' do
-      retraction = Retraction.for(post)
+      retraction = Retraction.for(@post)
       obj = retraction.instance_variable_get(:@object)
-      wanted_subscribers = obj.subscribers(user)
-      obj.should_receive(:subscribers).with(user).and_return(wanted_subscribers)
-      retraction.subscribers(user).map{|s| s.id}.should =~ wanted_subscribers.map{|s| s.id}
+      wanted_subscribers = obj.subscribers(alice)
+      obj.should_receive(:subscribers).with(alice).and_return(wanted_subscribers)
+      retraction.subscribers(alice).map{|s| s.id}.should =~ wanted_subscribers.map{|s| s.id}
     end
 
-    context 'hax' do
+    context 'setting subscribers' do
       it 'barfs if the type is a person, and subscribers instance varabile is not set' do
-        retraction = Retraction.for(user)
+        retraction = Retraction.for(alice)
         obj = retraction.instance_variable_get(:@object)
 
-        proc{retraction.subscribers(user)}.should raise_error
+        lambda {
+          retraction.subscribers(alice)
+        }.should raise_error
       end
 
       it 'returns manually set subscribers' do
-        retraction = Retraction.for(user)
+        retraction = Retraction.for(alice)
         retraction.subscribers = "fooey"
-        retraction.subscribers(user).should == 'fooey'
+        retraction.subscribers(alice).should == 'fooey'
       end
     end
   end
diff --git a/spec/models/service_user_spec.rb b/spec/models/service_user_spec.rb
index d58da22e74..1880a368c4 100644
--- a/spec/models/service_user_spec.rb
+++ b/spec/models/service_user_spec.rb
@@ -65,18 +65,6 @@ JSON
         @su.person.should be_nil
       end
 
-      context "request" do
-        before do
-          @request = Request.diaspora_initialize(:from => @user2.person, :to => @user.person, :into => @user2.aspects.first)
-          Postzord::Receiver.new(@user, :object => @request, :person => @user2.person).receive_object
-          Request.count.should == 1
-        end
-        it 'contains a request object if one has been sent' do
-          @su.save
-          @su.request.should == @request
-        end
-      end
-
       it 'contains a contact object if connected' do
         connect_users(@user, @user.aspects.first, @user2, @user2.aspects.first)
         @su.save
diff --git a/spec/models/user/connecting_spec.rb b/spec/models/user/connecting_spec.rb
index 836a419500..ba5d5cf4ba 100644
--- a/spec/models/user/connecting_spec.rb
+++ b/spec/models/user/connecting_spec.rb
@@ -16,53 +16,16 @@ describe Diaspora::UserModules::Connecting do
   let(:person_two) { Factory.create :person }
   let(:person_three) { Factory.create :person }
 
-  describe '#send_contact_request_to' do
-    it 'should not be able to contact request an existing contact' do
-      alice.activate_contact(eve.person, aspect1)
-
-      proc {
-        alice.send_contact_request_to(eve.person, aspect1)
-      }.should raise_error(ActiveRecord::RecordInvalid)
-    end
-
-    it 'should not be able to contact request no-one' do
-      proc {
-        alice.send_contact_request_to(nil, aspect)
-      }.should raise_error(ActiveRecord::RecordInvalid)
-    end
-    it 'creates a pending contact' do
-      proc {
-        alice.send_contact_request_to(eve.person, aspect1)
-      }.should change(Contact.unscoped, :count).by(1)
-      alice.contact_for(eve.person).pending.should == true
-      alice.contact_for(eve.person).should be_pending
-    end
-    it 'persists no request for requester' do
-      proc {
-        alice.send_contact_request_to(eve.person, aspect1)
-      }.should_not change{Request.where(:recipient_id => alice.person.id).count}
-    end
-    it 'persists a request for the recipient' do
-      alice.send_contact_request_to(eve.person, aspect1)
-      eve.request_from(alice.person).should_not be_nil
-    end
-  end
-
   context 'contact requesting' do
     describe  '#receive_contact_request' do
       before do
         @r = Request.diaspora_initialize(:to => alice.person, :from => person)
       end
 
-      it 'adds a request to pending if it was not sent by user' do
-        alice.receive_contact_request(@r)
-        Request.where(:recipient_id => alice.person.id).all.should include @r
-      end
-
       it 'creates no contact' do
         lambda {
           received_req = @r.receive(alice, person_one)
-        }.should_not change(Contact, :count)
+        }.should change(Contact, :count).by(1)
       end
     end
 
@@ -82,9 +45,6 @@ describe Diaspora::UserModules::Connecting do
     end
 
     context 'received a contact request' do
-      let(:request_for_user) {Request.diaspora_initialize(:to => alice.person, :from => person)}
-      let(:request2_for_user) {Request.diaspora_initialize(:to => alice.person, :from => person_one)}
-      let(:request_from_myself) {Request.diaspora_initialize(:to => alice.person, :from => alice.person)}
       before do
         Request.diaspora_initialize(:from => person, :to => alice.person).save
         Request.diaspora_initialize(:from => person_one, :to => alice.person).save
@@ -93,26 +53,8 @@ describe Diaspora::UserModules::Connecting do
         @received_request2 = Request.where(:sender_id => person_one.id, :recipient_id => alice.person.id).first
       end
 
-      it "should delete an accepted contact request" do
-        proc {
-          alice.accept_contact_request(@received_request, aspect)
-        }.should change(Request, :count ).by(-1)
-      end
-
-      it "should mark the corresponding notification as 'read'" do
-        notification = Factory.create(:notification, :target => @received_request)
-
-        Notification.where(:target_id=>@received_request.id).first.unread.should be_true
-        alice.accept_contact_request(@received_request, aspect)
-        Notification.where(:target_id=>@received_request.id).first.unread.should be_false
-      end
-
-      it 'should be able to ignore a pending contact request' do
-        proc { alice.ignore_contact_request(@received_request.id)
-        }.should change(Request, :count ).by(-1)
-      end
-
       it 'should ignore a contact request from yourself' do
+        request_from_myself = Request.diaspora_initialize(:to => alice.person, :from => alice.person)
         reversed_request = request_from_myself.reverse_for(alice)
 
         alice.receive_contact_request(reversed_request)
@@ -120,165 +62,49 @@ describe Diaspora::UserModules::Connecting do
       end
     end
 
-    describe 'multiple users accepting/rejecting the same person' do
-
-      before do
-        @request1 = Request.diaspora_initialize(:to => alice.person, :from => person_one)
-        @request2 = Request.diaspora_initialize(:to => eve.person, :from => person_one)
-        @request3 =  Request.diaspora_initialize(:to => eve.person, :from => alice.person)
-
-        @req1_xml = @request1.to_diaspora_xml
-        @req2_xml = @request2.to_diaspora_xml
-        @req3_xml = @request3.to_diaspora_xml
-
-        @request1.destroy
-        @request2.destroy
-        @request3.destroy
-      end
-
-      context 'request from one remote person to one local user' do
-        before do
-          zord = Postzord::Receiver.new(alice, :person => alice.person)
-          @received_request = zord.parse_and_receive(@req3_xml)
-          @received_request.reload
-        end
-
-        it 'should connect the user other user on the same pod' do
-          proc {
-            eve.accept_contact_request(@received_request, aspect2)
-          }.should_not change(Person, :count)
-          eve.contact_for(alice.person).should_not be_nil
-        end
-
-        it 'should not delete the ignored user on the same pod' do
-
-          proc {
-            eve.ignore_contact_request(@received_request.id)
-          }.should_not change(Person, :count)
-          eve.contact_for(alice.person).should be_nil
-        end
-      end
-
-      context 'Two users receiving requests from one person' do
-        before do
-          zord1 = Postzord::Receiver.new(alice, :person => person_one)
-          zord2 = Postzord::Receiver.new(alice, :person => person_one)
-
-          @req_to_user = zord1.parse_and_receive(@req1_xml)
-          @req_to_eve = zord2.parse_and_receive(@req2_xml)
+    describe 'disconnecting' do
+      describe '#remove_contact' do
+        it 'should remove the contact from all aspects they are in' do
+          contact = alice.contact_for(bob.person) 
+          new_aspect = alice.aspects.create(:name => 'new')
+          alice.add_contact_to_aspect( contact, new_aspect)
+
+          lambda { alice.remove_contact(contact) }.should change(
+          contact.aspects, :count).from(2).to(0)
         end
 
-        describe '#accept_contact_request' do
-          it 'should both users should connect the same person' do
-            alice.accept_contact_request @req_to_user, aspect
-            alice.contact_for(person_one).should_not be_nil
-
-            eve.accept_contact_request @req_to_eve, aspect2
-            eve.contact_for(person_one).should_not be_nil
-          end
-
-          it 'should keep the person around if one of the users rejects him' do
-            alice.accept_contact_request @req_to_user, aspect
-            alice.contact_for(person_one).should_not be_nil
+        context 'with a post' do
+          it "deletes the disconnected user's posts from visible_posts" do
+            StatusMessage.delete_all
+            message = alice.post(:status_message, :text => "hi", :to => alice.aspects.first.id)
 
-            eve.ignore_contact_request @req_to_eve.id
-            eve.contact_for(person_one).should be_nil
+            bob.reload.raw_visible_posts.include?(message).should be_true
+            bob.disconnect bob.contact_for(alice.person)
+            bob.reload.raw_visible_posts.include?(message).should be_false
           end
         end
-
-
-        it 'should keep the person around if the users ignores them' do
-          alice.ignore_contact_request Request.where(:recipient_id => alice.person.id).first.id
-          alice.contact_for(person_one).should be_nil
-
-          eve.ignore_contact_request Request.where(:recipient_id => eve.person.id).first.id
-          eve.contact_for(person_one).should be_nil
-        end
       end
 
+      describe '#disconnected_by' do
+        it 'removes a contacts mutual flag' do
+          pending 'needs migration'
+          alice.share_with(eve.person, alice.aspects.first)
 
-    end
-
-    describe 'a user accepting & rejecting multiple people' do
-      before do
-        request = Request.diaspora_initialize(:to => alice.person, :from => person_one)
-        @received_request = request.receive(alice, person_one)
-      end
-      describe '#accept_contact_request' do
-        it "deletes the received request" do
-          lambda {
-            alice.accept_contact_request(@received_request, aspect)
-          }.should change(Request, :count).by(-1)
-        end
-        it "creates a new contact" do
-          lambda {
-            alice.accept_contact_request(@received_request, aspect)
-          }.should change(Contact, :count).by(1)
-          alice.contact_for(person_one).should_not be_nil
-        end
-      end
-      describe '#ignore_contact_request' do
-        it "removes the request" do
-          lambda {
-            alice.ignore_contact_request(@received_request.id)
-          }.should change(Request, :count).by(-1)
-        end
-        it "creates no new contact" do
-          lambda {
-            alice.ignore_contact_request(@received_request)
-          }.should_not change(Contact, :count)
-        end
-      end
-    end
-
-    describe 'disconnecting' do
-
-      describe 'disconnected_by' do
-        it 'is disconnected by another user' do
-          lambda { alice.disconnected_by bob.person }.should change {
-            alice.contacts.count }.by(-1)
-          alice.aspects.first.contacts.count.should == 0
-        end
-
-        it 'deletes incoming requests' do
-          alice.send_contact_request_to(eve.person, alice.aspects.first)
-          Request.where(:recipient_id => eve.person.id, :sender_id => alice.person.id).first.should_not be_nil
+          alice.contacts.where(:person_id => eve.person.id).mutual.should be_true
           eve.disconnected_by(alice.person)
-          Request.where(:recipient_id => eve.person.id, :sender_id => alice.person.id).first.should be_nil
-        end
-      end
-
-      it 'disconnects a contact on the same seed' do
-        bob.aspects.first.contacts.count.should == 2
-        lambda {
-          bob.disconnect bob.contact_for(alice.person) }.should change {
-          bob.contacts(true).count }.by(-1)
-        bob.aspects.first.contacts(true).count.should == 1
-      end
-
-      it 'should remove the contact from all aspects they are in' do
-        new_aspect = alice.aspects.create(:name => 'new')
-        alice.add_contact_to_aspect( alice.contact_for(bob.person), new_aspect)
-        alice.aspects.first.reload.contacts.count.should == 1
-        new_aspect.reload.contacts.count.should == 1
-        lambda { alice.disconnected_by bob.person }.should change {
-          alice.contacts.count }.by(-1)
-        alice.aspects.first.reload.contacts.count.should == 0
-        new_aspect.reload.contacts.count.should == 0
-      end
+          alice.contacts.where(:person_id => eve.person.id).mutual.should be_false
 
-      context 'with a post' do
-        before do
-          StatusMessage.delete_all
-          @message = alice.post(:status_message, :text => "hi", :to => alice.aspects.first.id)
         end
+      end
 
-        it "deletes the disconnected user's posts from visible_posts" do
-          bob.reload.raw_visible_posts.include?(@message).should be_true
-          bob.disconnect bob.contact_for(alice.person)
-          bob.reload.raw_visible_posts.include?(@message).should be_false
+      describe '#disconnect' do
+        it 'disconnects a contact on the same seed' do
+          bob.aspects.first.contacts.count.should == 2
+          lambda {
+            bob.disconnect bob.contact_for(alice.person) }.should change {
+            bob.contacts(true).count }.by(-1)
+          bob.aspects.first.contacts(true).count.should == 1
         end
-
       end
     end
   end
@@ -314,5 +140,13 @@ describe Diaspora::UserModules::Connecting do
       contact.should_not_receive(:dispatch_request)
       alice.share_with(eve.person, alice.aspects.first)
     end
+
+    it "should mark the corresponding notification as 'read'" do
+      notification = Factory.create(:notification, :target => eve.person)
+
+      Notification.where(:target_id => eve.person.id).first.unread.should be_true
+      alice.share_with(eve.person, aspect)
+      Notification.where(:target_id => eve.person.id).first.unread.should be_false
+    end
   end
 end
diff --git a/spec/models/user/invite_spec.rb b/spec/models/user/invite_spec.rb
index 41343b472b..9d52f2e1ba 100644
--- a/spec/models/user/invite_spec.rb
+++ b/spec/models/user/invite_spec.rb
@@ -97,29 +97,7 @@ describe User do
       end
 
       it 'resolves incoming invitations into contact requests' do
-        Request.where(:recipient_id => invited_user.person.id).count.should == 1
-      end
-
-      context 'after request acceptance' do
-        before do
-          fantasy_resque do
-            invited_user.accept_and_respond(
-              Request.where(:recipient_id => invited_user.person.id).first.id,
-              invited_user.aspects.create(:name => 'first aspect!').id
-            )
-          end
-          invited_user.reload
-          inviter.reload
-        end
-        it 'successfully connects invited_user to inviter' do
-          invited_user.contact_for(inviter.person).should_not be_nil
-          invited_user.contact_for(inviter.person).should_not be_pending
-          Request.where(:recipient_id => invited_user.person.id).count.should == 0
-        end
-
-        it 'successfully connects inviter to invited_user' do
-          inviter.contact_for(invited_user.person).should_not be_pending
-        end
+        inviter.contacts.where(:person_id => invited_user.person.id).count.should == 1
       end
     end
   end
diff --git a/spec/models/user/posting_spec.rb b/spec/models/user/posting_spec.rb
index 1d04b741fe..5bafbb1b0c 100644
--- a/spec/models/user/posting_spec.rb
+++ b/spec/models/user/posting_spec.rb
@@ -5,83 +5,75 @@
 require 'spec_helper'
 
 describe User do
-
-  let!(:user) { alice }
-  let!(:user2) { eve }
-
-  let!(:aspect) { user.aspects.first }
-  let!(:aspect1) { user.aspects.create(:name => 'other') }
-  let!(:aspect2) { user2.aspects.first }
-
-  let!(:service1) { Factory(:service, :type => 'Services::Twitter' , :user => user) }
-  let!(:service2) { Factory(:service, :type => 'Services::Facebook', :user => user) }
+  before do
+    @aspect = alice.aspects.first
+    @aspect1 = alice.aspects.create(:name => 'other')
+  end
 
   describe '#add_to_streams' do
     before do
-      @params = {:text => "hey", :to => [aspect.id, aspect1.id]}
-      @post = user.build_post(:status_message, @params)
+      @params = {:text => "hey", :to => [@aspect.id, @aspect1.id]}
+      @post = alice.build_post(:status_message, @params)
       @post.save
       @aspect_ids = @params[:to]
-      @aspects = user.aspects_from_ids(@aspect_ids)
+      @aspects = alice.aspects_from_ids(@aspect_ids)
     end
 
     it 'saves post into visible post ids' do
-      proc {
-        user.add_to_streams(@post, @aspects)
-      }.should change{user.raw_visible_posts(:by_members_of => @aspects).length}.by(1)
-      user.raw_visible_posts(:by_members_of => @aspects).should include @post
+      lambda {
+        alice.add_to_streams(@post, @aspects)
+      }.should change{alice.raw_visible_posts(:by_members_of => @aspects).length}.by(1)
+      alice.raw_visible_posts(:by_members_of => @aspects).should include @post
     end
 
     it 'saves post into each aspect in aspect_ids' do
-      user.add_to_streams(@post, @aspects)
-      aspect.reload.post_ids.should include @post.id
-      aspect1.reload.post_ids.should include @post.id
+      alice.add_to_streams(@post, @aspects)
+      @aspect.reload.post_ids.should include @post.id
+      @aspect1.reload.post_ids.should include @post.id
     end
 
     it 'sockets the post to the poster' do
-      @post.should_receive(:socket_to_user).with(user, anything)
-      user.add_to_streams(@post, @aspects)
+      @post.should_receive(:socket_to_user).with(alice, anything)
+      alice.add_to_streams(@post, @aspects)
     end
   end
 
   describe '#aspects_from_ids' do
-    it 'returns a list of all valid aspects a user can post to' do
+    it 'returns a list of all valid aspects a alice can post to' do
       aspect_ids = Aspect.all.map(&:id)
-      user.aspects_from_ids(aspect_ids).map{|a| a}.should ==
-        user.aspects.map{|a| a} #Rspec matchers ftw
+      alice.aspects_from_ids(aspect_ids).to_set.should == alice.aspects.to_set
     end
     it "lets you post to your own aspects" do
-      user.aspects_from_ids([aspect.id]).should == [aspect]
-      user.aspects_from_ids([aspect1.id]).should == [aspect1]
+      alice.aspects_from_ids([@aspect.id]).should == [@aspect]
+      alice.aspects_from_ids([@aspect1.id]).should == [@aspect1]
     end
     it 'removes aspects that are not yours' do
-      user.aspects_from_ids(aspect2.id).should == []
+      alice.aspects_from_ids(eve.aspects.first.id).should == []
     end
   end
 
   describe '#build_post' do
-    it 'sets status_message#message' do
-      post = user.build_post(:status_message, :text => "hey", :to => aspect.id)
+    it 'sets status_message#text' do
+      post = alice.build_post(:status_message, :text => "hey", :to => @aspect.id)
       post.text.should == "hey"
     end
+
     it 'does not save a status_message' do
-      post = user.build_post(:status_message, :text => "hey", :to => aspect.id)
-      post.persisted?.should be_false
+      post = alice.build_post(:status_message, :text => "hey", :to => @aspect.id)
+      post.should_not be_persisted
     end
 
     it 'does not save a photo' do
-      post = user.build_post(:photo, :user_file => uploaded_photo, :to => aspect.id)
-      post.persisted?.should be_false
+      post = alice.build_post(:photo, :user_file => uploaded_photo, :to => @aspect.id)
+      post.should_not be_persisted
     end
-
   end
 
-
   describe '#update_post' do
     it 'should update fields' do
-      photo = user.post(:photo, :user_file => uploaded_photo, :text => "Old caption", :to => aspect.id)
+      photo = alice.post(:photo, :user_file => uploaded_photo, :text => "Old caption", :to => @aspect.id)
       update_hash = {:text => "New caption"}
-      user.update_post(photo, update_hash)
+      alice.update_post(photo, update_hash)
 
       photo.text.should match(/New/)
     end
diff --git a/spec/models/user/querying_spec.rb b/spec/models/user/querying_spec.rb
index 3224a1e78f..0acd76edd2 100644
--- a/spec/models/user/querying_spec.rb
+++ b/spec/models/user/querying_spec.rb
@@ -134,11 +134,12 @@ describe User do
     end
   end
 
-  context 'contact querying' do
+  context 'querying' do
     let(:person_one) { Factory.create :person }
     let(:person_two) { Factory.create :person }
     let(:person_three) { Factory.create :person }
     let(:aspect) { alice.aspects.create(:name => 'heroes') }
+
     describe '#contact_for_person_id' do
       it 'returns a contact' do
         contact = Contact.create(:user => alice, :person => person_one, :aspects => [aspect])
@@ -180,6 +181,24 @@ describe User do
         alice.contact_for(nil).should be_nil
       end
     end
+
+    describe '#aspects_with_person' do
+      before do
+        @connected_person = bob.person
+      end
+
+      it 'should return the aspects with given contact' do
+        alice.aspects_with_person(@connected_person).should == [alice.aspects.first]
+      end
+
+      it 'returns multiple aspects if the person is there' do
+        aspect2 = alice.aspects.create(:name => 'second')
+        contact = alice.contact_for(@connected_person)
+
+        alice.add_contact_to_aspect(contact, aspect2)
+        alice.aspects_with_person(@connected_person).to_set.should == alice.aspects.to_set
+      end
+    end
   end
 
   describe '#posts_from' do
diff --git a/spec/models/user_spec.rb b/spec/models/user_spec.rb
index 0fa5ffc4fd..0151d740d0 100644
--- a/spec/models/user_spec.rb
+++ b/spec/models/user_spec.rb
@@ -15,6 +15,7 @@ describe User do
         new_user = Factory.create(:user, :id => alice.id)
       }.should raise_error ActiveRecord::RecordNotUnique
     end
+
     it 'does not overwrite old users with create' do
           params = {:username => "ohai",
                     :email => "ohai@example.com",
@@ -36,7 +37,7 @@ describe User do
   describe "validation" do
     describe "of associated person" do
       it "fails if person is not valid" do
-        user = Factory.build(:user)
+        user = alice
         user.should be_valid
 
         user.person.serialized_public_key = nil
@@ -48,27 +49,15 @@ describe User do
       end
     end
 
-    describe "of passwords" do
-      it "fails if password doesn't match confirmation" do
-        user = Factory.build(:user, :password => "password", :password_confirmation => "nope")
-        user.should_not be_valid
-      end
-
-      it "succeeds if password matches confirmation" do
-        user = Factory.build(:user, :password => "password", :password_confirmation => "password")
-        user.should be_valid
-      end
-    end
-
     describe "of username" do
       it "requires presence" do
-        user = Factory.build(:user, :username => nil)
-        user.should_not be_valid
+        alice.username = nil
+        alice.should_not be_valid
       end
 
       it "requires uniqueness" do
-        duplicate_user = Factory.build(:user, :username => alice.username)
-        duplicate_user.should_not be_valid
+        alice.username = eve.username
+        alice.should_not be_valid
       end
 
       it "downcases username" do
@@ -78,51 +67,51 @@ describe User do
       end
 
       it "fails if the requested username is only different in case from an existing username" do
-        duplicate_user = Factory.build(:user, :username => alice.username.upcase)
-        duplicate_user.should_not be_valid
+        alice.username = eve.username.upcase
+        alice.should_not be_valid
       end
 
       it "strips leading and trailing whitespace" do
-        user = Factory.build(:user, :username => "    janie    ")
+        user = Factory.build(:user, :username => "      janie   ")
         user.should be_valid
         user.username.should == "janie"
       end
 
       it "fails if there's whitespace in the middle" do
-        user = Factory.build(:user, :username => "bobby tables")
-        user.should_not be_valid
+        alice.username = "bobby tables"
+        alice.should_not be_valid
       end
 
       it 'can not contain non url safe characters' do
-        user = Factory.build(:user, :username => "kittens;")
-        user.should_not be_valid
+        alice.username = "kittens;"
+        alice.should_not be_valid
       end
 
       it 'should not contain periods' do
-        user = Factory.build(:user, :username => "kittens.")
-        user.should_not be_valid
+        alice.username = "kittens."
+        alice.should_not be_valid
       end
 
       it "can be 32 characters long" do
-        user = Factory.build(:user, :username => "hexagoooooooooooooooooooooooooon")
-        user.should be_valid
+        alice.username = "hexagoooooooooooooooooooooooooon"
+        alice.should be_valid
       end
 
       it "cannot be 33 characters" do
-        user = Factory.build(:user, :username => "hexagooooooooooooooooooooooooooon")
-        user.should_not be_valid
+        alice.username =  "hexagooooooooooooooooooooooooooon"
+        alice.should_not be_valid
       end
     end
 
     describe "of email" do
       it "requires email address" do
-        user = Factory.build(:user, :email => nil)
-        user.should_not be_valid
+        alice.email = nil
+        alice.should_not be_valid
       end
 
       it "requires a unique email address" do
-        duplicate_user = Factory.build(:user, :email => alice.email)
-        duplicate_user.should_not be_valid
+        alice.email = eve.email
+        alice.should_not be_valid
       end
     end
 
@@ -130,9 +119,10 @@ describe User do
       after do
         I18n.locale = :en
       end
+
       it "requires availability" do
-        user = Factory.build(:user, :language => 'some invalid language')
-        user.should_not be_valid
+        alice.language = 'some invalid language'
+        alice.should_not be_valid
       end
 
       it "should save with current language if blank" do
@@ -141,8 +131,7 @@ describe User do
         user.language.should == 'fr'
       end
     end
-
-   end
+  end
 
   describe ".build" do
     context 'with valid params' do
@@ -159,11 +148,13 @@ describe User do
         }
         @user = User.build(params)
       end
+
       it "does not save" do
         @user.persisted?.should be_false
         @user.person.persisted?.should be_false
         User.find_by_username("ohai").should be_nil
       end
+
       it 'saves successfully' do
         @user.should be_valid
         @user.save.should be_true
@@ -172,6 +163,7 @@ describe User do
         User.find_by_username("ohai").should == @user
       end
     end
+
     describe "with invalid params" do
       before do
         @invalid_params = {
@@ -181,20 +173,25 @@ describe User do
           :password_confirmation => "wrongpasswordz",
           :person => {:profile => {:first_name => "", :last_name => ""}}}
       end
+
       it "raises no error" do
         lambda { User.build(@invalid_params) }.should_not raise_error
       end
+
       it "does not save" do
         User.build(@invalid_params).save.should be_false
       end
+
       it 'does not save a person' do
         lambda { User.build(@invalid_params) }.should_not change(Person, :count)
       end
+
       it 'does not generate a key' do
         User.should_receive(:generate_key).exactly(0).times
         User.build(@invalid_params)
       end
     end
+
     describe "with malicious params" do
       let(:person) {Factory.create :person}
       before do
@@ -210,6 +207,7 @@ describe User do
                     }
         }
       end
+
       it "does not assign it to the person" do
         User.build(@invalid_params).person.id.should_not == person.id
       end
@@ -244,6 +242,7 @@ describe User do
         alice.update_user_preferences({})
       }.should change(alice.user_preferences, :count).by(6)
     end
+
     it 'still sets new prefs to false on update' do
       alice.disable_mail = true
       proc {
@@ -257,9 +256,11 @@ describe User do
     it 'finds a user' do
       User.find_for_authentication(:username => alice.username).should == alice
     end
+
     it "does not preserve case" do
       User.find_for_authentication(:username => alice.username.upcase).should == alice
     end
+
     it 'errors out when passed a non-hash' do
       lambda {
         User.find_for_authentication(alice.username)
@@ -274,6 +275,7 @@ describe User do
         :last_name => 'billytown',
       }
     end
+
     it 'dispatches the profile when tags are set' do
       @params = {:tags => '#what #hey'}
       mailman = Postzord::Dispatch.new(alice, Profile.new)
@@ -281,22 +283,26 @@ describe User do
       mailman.should_receive(:deliver_to_local)
       alice.update_profile(@params).should be_true
     end
+
     it 'sends a profile to their contacts' do
       mailman = Postzord::Dispatch.new(alice, Profile.new)
       Postzord::Dispatch.should_receive(:new).and_return(mailman)
       mailman.should_receive(:deliver_to_local)
       alice.update_profile(@params).should be_true
     end
+
     it 'updates names' do
       alice.update_profile(@params).should be_true
       alice.reload.profile.first_name.should == 'bob'
     end
+
     it 'updates image_url' do
       params = {:image_url => "http://clown.com"}
 
       alice.update_profile(params).should be_true
       alice.reload.profile.image_url.should == "http://clown.com"
     end
+
     context 'passing in a photo' do
       before do
         fixture_filename  = 'button.png'
@@ -306,6 +312,7 @@ describe User do
         @photo.save!
         @params = {:photo => @photo}
       end
+
       it 'updates image_url' do
         alice.update_profile(@params).should be_true
         alice.reload
@@ -314,6 +321,7 @@ describe User do
         alice.profile.image_url_medium.should =~ Regexp.new(@photo.url(:thumb_medium))
         alice.profile.image_url_small.should =~ Regexp.new(@photo.url(:thumb_small))
       end
+
       it 'unpends the photo' do
         @photo.pending = true
         @photo.save!
@@ -455,7 +463,6 @@ describe User do
     end
 
     describe '#disconnect_everyone' do
-
       it 'has no error on a local friend who has deleted his account' do
         alice.destroy
         lambda {
@@ -473,9 +480,8 @@ describe User do
       it 'should send retractions to remote poeple' do
         person = eve.person
         eve.delete
-        person.owner_id = nil
         person.save
-        alice.activate_contact(person, alice.aspects.first)
+        alice.contacts.create(:person => person, :aspects => [alice.aspects.first])
 
         alice.should_receive(:disconnect).once
         alice.destroy
@@ -493,7 +499,6 @@ describe User do
     it 'enqueues a mail job' do
       alice.disable_mail = false
       alice.save
-      alice.reload
 
       Resque.should_receive(:enqueue).with(Job::MailRequestReceived, alice.id, 'contactrequestid').once
       alice.mail(Job::MailRequestReceived, alice.id, 'contactrequestid')
@@ -506,4 +511,50 @@ describe User do
     end
   end
 
+  context "aspect management" do
+    before do
+      @contact = alice.contact_for(bob.person)
+      @aspect1 = alice.aspects.create(:name => 'two')
+    end
+
+    describe "#add_contact_to_aspect" do
+      it 'adds the contact to the aspect' do
+        lambda { 
+          alice.add_contact_to_aspect(@contact, @aspect1)
+        }.should change(@aspect1.contacts, :count).by(1)
+      end
+
+      it 'returns true if they are already in the aspect' do
+        alice.add_contact_to_aspect(@contact, alice.aspects.first).should be_true
+      end
+    end
+
+    context 'moving and removing posts' do
+      describe 'User#move_contact' do
+        it 'should be able to move a contact from one of users existing aspects to another' do
+          alice.move_contact(bob.person, @aspect1, alice.aspects.first)
+
+          alice.aspects.first.contacts(true).include?(@contact).should be_false
+          @aspect1.contacts(true).include?(@contact).should be_true
+        end
+
+        it "should not move a person who is not a contact" do
+          non_contact = eve.person
+
+          proc{
+            alice.move_contact(non_contact, @aspect1, alice.aspects.first)
+          }.should raise_error
+
+          alice.aspects.first.contacts.where(:person_id => non_contact.id).should be_empty
+          @aspect1.contacts.where(:person_id => non_contact.id).should be_empty
+        end
+
+        it 'does not try to delete if add person did not go through' do
+          alice.should_receive(:add_contact_to_aspect).and_return(false)
+          alice.should_not_receive(:delete_person_from_aspect)
+          alice.move_contact(bob.person, @aspect1, alice.aspects.first)
+        end
+      end
+    end
+  end
 end
diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb
index 399817e576..d95fe6c5d8 100644
--- a/spec/spec_helper.rb
+++ b/spec/spec_helper.rb
@@ -49,8 +49,9 @@ def set_up_friends
   local_leia = Factory(:user_with_aspect, :username => "leia")
   remote_raphael = Factory(:person, :diaspora_handle => "raphael@remote.net")
   connect_users_with_aspects(local_luke, local_leia)
-  local_leia.activate_contact(remote_raphael, local_leia.aspects.first)
-  local_luke.activate_contact(remote_raphael, local_luke.aspects.first)
+
+  local_leia.contacts.create(:person => remote_raphael, :aspects => [local_leia.aspects.first])
+  local_luke.contacts.create(:person => remote_raphael, :aspects => [local_luke.aspects.first])
 
   [local_luke, local_leia, remote_raphael]
 end
-- 
GitLab