added mutual flag, removed pending from contact, specs are green. wip

This commit is contained in:
danielgrippi 2011-04-05 16:12:53 -07:00
parent 07f7eff782
commit 68375fdb02
34 changed files with 219 additions and 314 deletions

1
.rspec
View file

@ -1,3 +1,4 @@
--format Fuubar --format Fuubar
--profile --profile
--color --color
--tag ~performance

View file

@ -64,7 +64,6 @@ class AspectMembershipsController < ApplicationController
end end
end end
def update def update
@person = Person.find(params[:person_id]) @person = Person.find(params[:person_id])
@from_aspect = current_user.aspects.where(:id => params[:aspect_id]).first @from_aspect = current_user.aspects.where(:id => params[:aspect_id]).first

View file

@ -78,7 +78,7 @@ class PeopleController < ApplicationController
@contacts_of_contact = [] @contacts_of_contact = []
end end
if (@person != current_user.person) && (!@contact || @contact.pending) if (@person != current_user.person) && (!@contact || @contact.mutual)
@commenting_disabled = true @commenting_disabled = true
else else
@commenting_disabled = false @commenting_disabled = false

View file

@ -5,7 +5,7 @@
class Aspect < ActiveRecord::Base class Aspect < ActiveRecord::Base
belongs_to :user belongs_to :user
has_many :aspect_memberships has_many :aspect_memberships, :dependent => :destroy
has_many :contacts, :through => :aspect_memberships has_many :contacts, :through => :aspect_memberships
has_many :aspect_visibilities has_many :aspect_visibilities

View file

@ -9,14 +9,4 @@ class AspectMembership < ActiveRecord::Base
has_one :user, :through => :contact has_one :user, :through => :contact
has_one :person, :through => :contact has_one :person, :through => :contact
before_destroy :ensure_membership
def ensure_membership
if self.contact.aspect_memberships.count == 1
errors[:base] << I18n.t('shared.contact_list.cannot_remove')
false
else
true
end
end
end end

View file

@ -3,8 +3,6 @@
# the COPYRIGHT file. # the COPYRIGHT file.
class Contact < ActiveRecord::Base class Contact < ActiveRecord::Base
default_scope where(:pending => false)
belongs_to :user belongs_to :user
validates_presence_of :user validates_presence_of :user

View file

@ -19,7 +19,7 @@ class Invitation < ActiveRecord::Base
if opts[:from].contact_for(opts[:from].person) if opts[:from].contact_for(opts[:from].person)
raise "You are already connceted to this person" raise "You are already connceted to this person"
elsif not existing_user.invited? elsif not existing_user.invited?
opts[:from].send_contact_request_to(existing_user.person, opts[:into]) opts[:from].share_with(existing_user.person, opts[:into])
return return
elsif Invitation.where(:sender_id => opts[:from].id, :recipient_id => existing_user.id).first elsif Invitation.where(:sender_id => opts[:from].id, :recipient_id => existing_user.id).first
raise "You already invited this person" raise "You already invited this person"

View file

@ -3,8 +3,6 @@
# the COPYRIGHT file. # the COPYRIGHT file.
class PostVisibility < ActiveRecord::Base class PostVisibility < ActiveRecord::Base
default_scope where(:hidden => false)
belongs_to :contact belongs_to :contact
belongs_to :post belongs_to :post
end end

View file

@ -66,10 +66,7 @@ class Request < ActiveRecord::Base
def receive(user, person) def receive(user, person)
Rails.logger.info("event=receive payload_type=request sender=#{self.sender} to=#{self.recipient}") Rails.logger.info("event=receive payload_type=request sender=#{self.sender} to=#{self.recipient}")
user.contacts.create(:person_id => person.id)
user.contacts.create(:person_id => person.id, :pending => false)
#user.receive_contact_request(self)
self.save self.save
self self
end end

View file

@ -328,15 +328,15 @@ class User < ActiveRecord::Base
end end
def disconnect_everyone def disconnect_everyone
Contact.unscoped.where(:user_id => self.id).each { |contact| self.contacts.each do |contact|
unless contact.person.owner.nil? unless contact.person.owner.nil?
contact.person.owner.disconnected_by self.person contact.person.owner.disconnected_by(self.person)
remove_contact(contact) remove_contact(contact, :force => true)
else else
self.disconnect contact self.disconnect(contact)
end end
} end
self.aspects.delete_all self.aspects.destroy_all
end end
def remove_mentions def remove_mentions

View file

@ -10,4 +10,4 @@
%ul %ul
- for aspect in aspects - for aspect in aspects
= render 'aspects/aspect', :aspect => aspect, :contacts => aspect.contacts.reject{|x| x.pending == true} = render 'aspects/aspect', :aspect => aspect, :contacts => aspect.contacts

View file

@ -5,11 +5,9 @@
- content_for :head do - content_for :head do
=javascript_include_tag 'contact-list' =javascript_include_tag 'contact-list'
.aspects .aspects
- if !contact || !contact.persisted?
- elsif contact.pending / TODO(*) add following method in contact
%h4 - if contact && contact.persisted?
= t('people.person.pending_request')
- else
.badges{:class => ("hidden" if !contact.persisted?)} .badges{:class => ("hidden" if !contact.persisted?)}
= aspect_badges(aspects_with_person, :link => true) = aspect_badges(aspects_with_person, :link => true)
%p %p

View file

@ -35,7 +35,7 @@
%br %br
%hr{:style=>"width:300px;"} %hr{:style=>"width:300px;"}
-if user_signed_in? && ((contact.persisted? && !contact.pending?) || person == current_user.person || @incoming_request) -if user_signed_in? && ((contact.persisted? && contact.mutual?) || person == current_user.person || @incoming_request)
%ul#profile_information %ul#profile_information
- unless person.profile.bio.blank? - unless person.profile.bio.blank?
%li %li

View file

@ -36,7 +36,7 @@
= javascript_tag "$(document).ready(function() {jQuery.facebox({ ajax: '#{new_contact_path(:person_id => @person.id)}' });});" = javascript_tag "$(document).ready(function() {jQuery.facebox({ ajax: '#{new_contact_path(:person_id => @person.id)}' });});"
- else - else
- if user_signed_in? && @contact.person && @contact.pending? == false - if user_signed_in? && @contact.mutual?
.right .right
= link_to t('.mention'), new_status_message_path(:person_id => @person.id), :class => 'button', :rel => 'facebox' = link_to t('.mention'), new_status_message_path(:person_id => @person.id), :class => 'button', :rel => 'facebox'
= link_to t('.message'), new_conversation_path(:contact_id => @contact.id, :name => @contact.person.name, :contact_id => @contact.id), :class => 'button', :rel => 'facebox' = link_to t('.message'), new_conversation_path(:contact_id => @contact.id, :name => @contact.person.name, :contact_id => @contact.id), :class => 'button', :rel => 'facebox'

View file

@ -1,7 +1,8 @@
%li.remote_friend{:id => "uid_" + friend.uid, :uid => friend.uid} %li.remote_friend{:id => "uid_" + friend.uid, :uid => friend.uid}
.right .right
-if friend.contact && !friend.contact.pending -if friend.contact
= t('people.person.already_connected') / TODO(*) add following method in Contact
sharing
- elsif friend.invitation_id - elsif friend.invitation_id
= t('invitations.new.already_invited') = t('invitations.new.already_invited')
%br %br

View file

@ -0,0 +1,42 @@
class ContactRemovePendingAddMutual < ActiveRecord::Migration
def self.up
add_column :contacts, :mutual, :boolean, :default => false, :null => false
execute( <<SQL
UPDATE contacts
SET contacts.mutual = true
WHERE contacts.pending = false
SQL
)
remove_foreign_key "contacts", "people"
remove_index :contacts, [:person_id, :pending]
remove_index :contacts, [:user_id, :pending]
add_index :contacts, :person_id
add_foreign_key "contacts", "people", :name => "contacts_person_id_fk", :dependent => :delete
remove_column :contacts, :pending
end
def self.down
remove_foreign_key "contacts", "people"
remove_index :contacts, :person_id
add_column :contacts, :pending, :default => true, :null => false
add_index :contacts, [:user_id, :pending]
add_index :contacts, [:person_id, :pending]
add_foreign_key "contacts", "people", :name => "contacts_person_id_fk", :dependent => :delete
execute( <<SQL
UPDATE contacts
SET contacts.pending = false
WHERE contacts.mutual = true
SQL
)
remove_column :contacts, :mutual
end
end

View file

@ -10,7 +10,7 @@
# #
# It's strongly recommended to check this file into your version control system. # It's strongly recommended to check this file into your version control system.
ActiveRecord::Schema.define(:version => 20110331222629) do ActiveRecord::Schema.define(:version => 20110405171412) do
create_table "aspect_memberships", :force => true do |t| create_table "aspect_memberships", :force => true do |t|
t.integer "aspect_id", :null => false t.integer "aspect_id", :null => false
@ -70,15 +70,14 @@ ActiveRecord::Schema.define(:version => 20110331222629) do
create_table "contacts", :force => true do |t| create_table "contacts", :force => true do |t|
t.integer "user_id", :null => false t.integer "user_id", :null => false
t.integer "person_id", :null => false t.integer "person_id", :null => false
t.boolean "pending", :default => true, :null => false
t.datetime "created_at" t.datetime "created_at"
t.datetime "updated_at" t.datetime "updated_at"
t.string "mongo_id" t.string "mongo_id"
t.boolean "mutual", :default => false, :null => false
end end
add_index "contacts", ["mongo_id"], :name => "index_contacts_on_mongo_id" add_index "contacts", ["mongo_id"], :name => "index_contacts_on_mongo_id"
add_index "contacts", ["person_id", "pending"], :name => "index_contacts_on_person_id_and_pending" add_index "contacts", ["person_id"], :name => "index_contacts_on_person_id"
add_index "contacts", ["user_id", "pending"], :name => "index_contacts_on_user_id_and_pending"
add_index "contacts", ["user_id", "person_id"], :name => "index_contacts_on_user_id_and_person_id", :unique => true add_index "contacts", ["user_id", "person_id"], :name => "index_contacts_on_user_id_and_person_id", :unique => true
create_table "conversation_visibilities", :force => true do |t| create_table "conversation_visibilities", :force => true do |t|
@ -250,6 +249,7 @@ ActiveRecord::Schema.define(:version => 20110331222629) do
add_index "posts", ["status_message_id", "pending"], :name => "index_posts_on_status_message_id_and_pending" add_index "posts", ["status_message_id", "pending"], :name => "index_posts_on_status_message_id_and_pending"
add_index "posts", ["status_message_id"], :name => "index_posts_on_status_message_id" add_index "posts", ["status_message_id"], :name => "index_posts_on_status_message_id"
add_index "posts", ["type", "pending", "id"], :name => "index_posts_on_type_and_pending_and_id" add_index "posts", ["type", "pending", "id"], :name => "index_posts_on_type_and_pending_and_id"
add_index "posts", ["type"], :name => "index_posts_on_type"
create_table "profiles", :force => true do |t| create_table "profiles", :force => true do |t|
t.string "diaspora_handle" t.string "diaspora_handle"

View file

@ -5,7 +5,6 @@
module Diaspora module Diaspora
module UserModules module UserModules
module Connecting module Connecting
def share_with(person, aspect) def share_with(person, aspect)
contact = self.contacts.find_or_initialize_by_person_id(person.id) contact = self.contacts.find_or_initialize_by_person_id(person.id)
unless contact.persisted? unless contact.persisted?
@ -21,87 +20,32 @@ module Diaspora
contact contact
end end
def receive_contact_request(request) def receive_contact_request(request)
self.contacts.find_or_create_by_person_id(request.sender.id) contact = self.contacts.find_or_initialize_by_person_id(request.sender.id)
request if contact.persisted? && !contact.mutual?
contact.mutual = true
end end
=begin
def send_contact_request_to(desired_contact, aspect)
self.contacts.new(:person => desired_contact,
:pending => true)
contact.aspects << aspect
if contact.save!
request = contact.dispatch_request
request
else
nil
end
end
def dispatch_contact_acceptance(request, requester)
Postzord::Dispatch.new(self, request).post
request.destroy unless request.sender.owner
end
def accept_contact_request(request, aspect)
activate_contact(request.sender, aspect)
if notification = Notification.where(:target_id=>request.id).first
notification.update_attributes(:unread=>false)
end
request.destroy
request.reverse_for(self)
end
def accept_and_respond(contact_request_id, aspect_id)
request = Request.where(:recipient_id => self.person.id, :id => contact_request_id).first
requester = request.sender
reversed_request = accept_contact_request(request, aspects.where(:id => aspect_id).first )
dispatch_contact_acceptance reversed_request, requester
end
def ignore_contact_request(contact_request_id)
request = Request.where(:recipient_id => self.person.id, :id => contact_request_id).first
request.destroy
end
def receive_contact_request(contact_request)
#response from a contact request you sent
if original_contact = self.contact_for(contact_request.sender)
receive_request_acceptance(contact_request, original_contact)
#this is a new contact request
elsif contact_request.sender != self.person
if contact_request.save!
Rails.logger.info("event=contact_request status=received_new_request from=#{contact_request.sender.diaspora_handle} to=#{self.diaspora_handle}")
end
else
Rails.logger.info "event=contact_request status=abort from=#{contact_request.sender.diaspora_handle} to=#{self.diaspora_handle} reason=self-love"
return nil
end
contact_request
end
def receive_request_acceptance(received_request, contact)
contact.pending = false
contact.save contact.save
Rails.logger.info("event=contact_request status=received_acceptance from=#{received_request.sender.diaspora_handle} to=#{self.diaspora_handle}") request
received_request.destroy
self.save
end end
def activate_contact(person, aspect) def remove_contact(contact, opts={:force => false})
new_contact = Contact.create!(:user => self, posts = contact.posts.all
:person => person,
:aspects => [aspect], if !contact.mutual || opts[:force]
:pending => false) contact.destroy
else
contact.update_attributes(:mutual => false)
contact.post_visibilities.destroy_all
contact.aspect_memberships.destroy_all
end
posts.each do |p|
if p.user_refs < 1
p.destroy
end
end
end end
=end
def disconnect(bad_contact) def disconnect(bad_contact)
person = bad_contact.person person = bad_contact.person
@ -112,24 +56,12 @@ module Diaspora
remove_contact(bad_contact) remove_contact(bad_contact)
end end
def remove_contact(contact)
bad_person_id = contact.person_id
posts = contact.posts.all
contact.destroy
posts.each do |post|
if post.user_refs < 1
post.destroy
end
end
end
def disconnected_by(person) def disconnected_by(person)
Rails.logger.info("event=disconnected_by user=#{diaspora_handle} target=#{person.diaspora_handle}") Rails.logger.info("event=disconnected_by user=#{diaspora_handle} target=#{person.diaspora_handle}")
if contact = self.contact_for(person) if contact = self.contact_for(person)
remove_contact(contact) remove_contact(contact)
end end
end end
end end
end end
end end

View file

@ -48,7 +48,7 @@ module Diaspora
end end
def contact_for_person_id(person_id) def contact_for_person_id(person_id)
Contact.unscoped.where(:user_id => self.id, :person_id => person_id).includes(:person => :profile).first if person_id Contact.where(:user_id => self.id, :person_id => person_id).includes(:person => :profile).first
end end
def people_in_aspects(requested_aspects, opts={}) def people_in_aspects(requested_aspects, opts={})

View file

@ -34,7 +34,6 @@ describe AspectMembershipsController do
end end
end end
describe "#destroy" do describe "#destroy" do
it 'removes contacts from an aspect' do it 'removes contacts from an aspect' do
@user.add_contact_to_aspect(@contact, @aspect1) @user.add_contact_to_aspect(@contact, @aspect1)
@ -47,17 +46,6 @@ describe AspectMembershipsController do
@aspect0.contacts.include?(@contact).should be false @aspect0.contacts.include?(@contact).should be false
end end
describe "#update" do
it 'calls the move_contact method' do
@controller.stub!(:current_user).and_return(@user)
@user.should_receive(:move_contact)
put :update, :id => 123,
:person_id => @user.person.id,
:aspect_id => @aspect0.id,
:to => @aspect1.id
end
end
context 'aspect membership does not exist' do context 'aspect membership does not exist' do
it 'person does not exist' do it 'person does not exist' do
delete :destroy, delete :destroy,
@ -77,14 +65,16 @@ describe AspectMembershipsController do
response.body.should include "Could not find the selected person in that aspect" response.body.should include "Could not find the selected person in that aspect"
end end
end end
end
it 'has the error of cannot delete contact from last aspect if its the last aspect' do describe "#update" do
delete :destroy, it 'calls the move_contact method' do
:format => 'js', :id => 123, @controller.stub!(:current_user).and_return(@user)
:person_id => @user2.person.id, @user.should_receive(:move_contact)
:aspect_id => @aspect0.id put :update, :id => 123,
response.should_not be_success :person_id => @user.person.id,
response.body.should include "Cannot remove person from last aspect" :aspect_id => @aspect0.id,
:to => @aspect1.id
end end
end end
end end

View file

@ -142,7 +142,7 @@ describe AspectsController do
get :index get :index
assigns(:posts).should == @posts.reverse assigns(:posts).should == @posts.reverse
get :index, :sort_order => "updated_at" get :index, :sort_order => "updated_at"
assigns(:posts).should == @posts assigns(:posts).map(&:id).should == @posts.map(&:id)
end end
it "doesn't allow SQL injection" do it "doesn't allow SQL injection" do
@ -232,6 +232,7 @@ describe AspectsController do
get :manage get :manage
response.should be_success response.should be_success
end end
it "performs reasonably", :performance => true do it "performs reasonably", :performance => true do
require 'benchmark' require 'benchmark'
8.times do |n| 8.times do |n|
@ -245,32 +246,31 @@ describe AspectsController do
get :manage get :manage
}.should < 4.5 }.should < 4.5
end end
it "assigns aspect to manage" do it "assigns aspect to manage" do
get :manage get :manage
assigns(:aspect).should == :manage assigns(:aspect).should == :manage
end end
it "assigns contacts to only non-pending" do
contact = @alice.contact_for(bob.person)
Contact.unscoped.where(:user_id => @alice.id).count.should == 1
@alice.send_contact_request_to(Factory(:user).person, @alices_aspect_1)
Contact.unscoped.where(:user_id => @alice.id).count.should == 2
it "assigns contacts" do
get :manage get :manage
contacts = assigns(:contacts) contacts = assigns(:contacts)
contacts.count.should == 1 contacts.to_set.should == alice.contacts.to_set
contacts.first.should == contact
end end
end end
describe "#update" do describe "#update" do
before do it "doesn't overwrite name" do
@alices_aspect_1 = @alice.aspects.create(:name => "Bruisers") @alices_aspect_1 = @alice.aspects.create(:name => "Bruisers")
end
it "doesn't overwrite random attributes" do
new_user = Factory.create :user new_user = Factory.create :user
params = {"name" => "Bruisers"} params = {"name" => "Bruisers"}
params[:user_id] = new_user.id params[:user_id] = new_user.id
put('update', :id => @alices_aspect_1.id, "aspect" => params)
put(:update, :id => @alices_aspect_1.id, :aspect => params)
Aspect.find(@alices_aspect_1.id).user_id.should == @alice.id Aspect.find(@alices_aspect_1.id).user_id.should == @alice.id
end end
end end

View file

@ -5,15 +5,11 @@ module HelperMethods
def connect_users(user1, aspect1, user2, aspect2) def connect_users(user1, aspect1, user2, aspect2)
user1.contacts.create!(:person => user2.person, user1.contacts.create!(:person => user2.person,
:aspects => [aspect1], :aspects => [aspect1],
:pending => false) :mutual => true)
user2.contacts.create!(:person => user1.person, user2.contacts.create!(:person => user1.person,
:aspects => [aspect2], :aspects => [aspect2],
:pending => false) :mutual => true)
user1.reload
user2.reload
aspect1.reload
aspect2.reload
end end
def stub_success(address = 'abc@example.com', opts = {}) def stub_success(address = 'abc@example.com', opts = {})

View file

@ -83,7 +83,7 @@ describe 'a user receives a post' do
it 'notifies users when receiving a mention in a post from a remote user' do 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") @remote_person = Factory.create(:person, :diaspora_handle => "foobar@foobar.com")
Contact.create!(:user => alice, :person => @remote_person, :aspects => [@aspect], :pending => false) Contact.create!(:user => alice, :person => @remote_person, :aspects => [@aspect])
Notification.should_receive(:notify).with(alice, anything(), @remote_person) Notification.should_receive(:notify).with(alice, anything(), @remote_person)
@ -153,8 +153,8 @@ describe 'a user receives a post' do
end end
it "adds a received post to the the contact" do it "adds a received post to the the contact" do
alice.raw_visible_posts.include?(@status_message).should be_true alice.raw_visible_posts.should include(@status_message)
@contact.posts.include?(@status_message).should be_true @contact.posts.should include(@status_message)
end end
it 'removes posts upon disconnecting' do it 'removes posts upon disconnecting' do
@ -177,7 +177,7 @@ describe 'a user receives a post' do
@post.post_visibilities.reset @post.post_visibilities.reset
end end
it 'deletes a post if the noone links to it' do it 'deletes a post if the no one links to it' do
lambda { lambda {
alice.disconnected_by(@person) alice.disconnected_by(@person)
}.should change(Post, :count).by(-1) }.should change(Post, :count).by(-1)

View file

@ -5,30 +5,15 @@
require 'spec_helper' require 'spec_helper'
describe AspectMembership do describe AspectMembership do
before do
@user = alice describe '#before_delete' do
@user2 = bob it 'calls disconnect' do
@aspect = @user.aspects.create(:name => 'Boozers') pending
@contact = @user.contact_for(@user2.person) alice.should_receive(:disconnect).with(alice.contact_for(bob))
alice.aspects.create(:name => "two")
alice.aspects.first.destroy
end
end end
it 'has an aspect' do
am = AspectMembership.new(:aspect => @aspect)
am.aspect.should == @aspect
end
it 'has a contact' do
am = AspectMembership.new(:contact => @contact)
am.contact.should == @contact
end
context 'validations' do
describe '#ensure_membership' do
it 'does not destroy from the final aspect' do
am = @contact.aspect_memberships.first
am.destroy
am.errors.should_not be_empty
end
end
end
end end

View file

@ -7,7 +7,6 @@ require 'spec_helper'
describe Invitation do describe Invitation do
let(:user) { alice } let(:user) { alice }
let(:aspect) { user.aspects.first } let(:aspect) { user.aspects.first }
let(:user2) { eve }
before do before do
user.invites = 20 user.invites = 20
@ -18,11 +17,11 @@ describe Invitation do
describe 'validations' do describe 'validations' do
before do before do
aspect aspect
@invitation = Invitation.new(:sender => user, :recipient => user2, :aspect => aspect) @invitation = Invitation.new(:sender => user, :recipient => eve, :aspect => aspect)
end end
it 'is valid' do it 'is valid' do
@invitation.sender.should == user @invitation.sender.should == user
@invitation.recipient.should == user2 @invitation.recipient.should == eve
@invitation.aspect.should == aspect @invitation.aspect.should == aspect
@invitation.should be_valid @invitation.should be_valid
end end
@ -41,7 +40,7 @@ describe Invitation do
end end
it 'has a message' do it 'has a message' do
@invitation = Invitation.new(:sender => user, :recipient => user2, :aspect => aspect) @invitation = Invitation.new(:sender => user, :recipient => eve, :aspect => aspect)
@invitation.message = "!" @invitation.message = "!"
@invitation.message.should == "!" @invitation.message.should == "!"
end end
@ -54,7 +53,7 @@ describe Invitation do
@identifier = "maggie@example.org" @identifier = "maggie@example.org"
inv.invitation_identifier.should == @identifier inv.invitation_identifier.should == @identifier
inv.invitation_service.should == 'email' inv.invitation_service.should == 'email'
inv.persisted?.should be_false inv.should_not be_persisted
lambda { lambda {
inv.reload inv.reload
}.should raise_error ActiveRecord::RecordNotFound }.should raise_error ActiveRecord::RecordNotFound
@ -162,12 +161,8 @@ describe Invitation do
end end
it 'sends a contact request to a user with that email into the aspect' do it 'sends a contact request to a user with that email into the aspect' do
user2 user.should_receive(:share_with).with(eve.person, aspect)
user.should_receive(:send_contact_request_to) { |a, b| Invitation.invite(:from => user, :service => 'email', :identifier => eve.email, :into => aspect)
a.should == user2.person
b.should == aspect
}
Invitation.invite(:from => user, :service => 'email', :identifier => user2.email, :into => aspect)
end end
it 'decrements the invite count of the from user' do it 'decrements the invite count of the from user' do
@ -322,10 +317,10 @@ describe Invitation do
}.should change(Invitation, :count).by(-1) }.should change(Invitation, :count).by(-1)
end end
it 'creates a contact for the inviter' do it 'creates a contact for the inviter and invitee' do
lambda { lambda {
@invitation.share_with! @invitation.share_with!
}.should change(Contact.unscoped, :count).by(1) }.should change(Contact, :count).by(2)
end end
end end
end end

View file

@ -301,7 +301,7 @@ describe Person do
@casey_grippi.profile.first_name = "AAA" @casey_grippi.profile.first_name = "AAA"
@casey_grippi.profile.save @casey_grippi.profile.save
requestor.send_contact_request_to(@user.person, requestor.aspects.first) requestor.share_with(@user.person, requestor.aspects.first)
people = Person.search("AAA", @user) people = Person.search("AAA", @user)
people.map{|p| p.name}.should == [requestor.person, @yevgeniy_dodis, @robert_grimm, @casey_grippi, @eugene_weinstein].map{|p|p.name} people.map{|p| p.name}.should == [requestor.person, @yevgeniy_dodis, @robert_grimm, @casey_grippi, @eugene_weinstein].map{|p|p.name}
end end

View file

@ -1,22 +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'
describe PostVisibility do
before do
@alice = alice
@bob = bob
@status = @alice.post(:status_message, :text => "hello", :public => true, :to => @alice.aspects.first)
@vis = @status.post_visibilities.first
@vis.hidden = true
@vis.save
end
it 'is default scoped to not-hidden' do
PostVisibility.where(:id => @vis.id).should == []
PostVisibility.unscoped.where(:id => @vis.id).should == [@vis]
end
end

View file

@ -56,7 +56,8 @@ describe Request do
end end
it 'returns request_accepted' do it 'returns request_accepted' do
@user.contacts.create(:person_id => @person.id, :pending => true) pending 'TODO(*) take out request accepted'
@user.contacts.create(:person_id => @person.id)
@request.notification_type(@user, @person).should == Notifications::RequestAccepted @request.notification_type(@user, @person).should == Notifications::RequestAccepted
end end

View file

@ -22,23 +22,33 @@ describe Diaspora::UserModules::Connecting do
@r = Request.diaspora_initialize(:to => alice.person, :from => person) @r = Request.diaspora_initialize(:to => alice.person, :from => person)
end end
it 'creates no contact' do it 'creates a contact' do
lambda { lambda {
received_req = @r.receive(alice, person_one) received_req = @r.receive(alice, person_one)
}.should change(Contact, :count).by(1) }.should change(Contact, :count).by(1)
end end
end end
describe '#receive_request_acceptance' do describe '#receive_contact_request' do
before do before do
@original_request = alice.send_contact_request_to(eve.person, aspect) @request = Request.new(:sender => eve.person, :recipient => alice.person)
@acceptance = @original_request.reverse_for(eve)
end end
it 'connects to the acceptor' do it 'sets mutual on an existing contact' do
alice.receive_contact_request(@acceptance) alice.share_with(eve.person, aspect)
alice.contact_for(eve.person).should_not be_nil lambda{
alice.receive_contact_request(@request)
}.should change{
alice.contacts.find_by_person_id(eve.person.id).mutual
}.from(false).to(true)
end end
it 'deletes the acceptance' do
it 'does not set mutual' do
alice.receive_contact_request(@request)
alice.contacts.find_by_person_id(eve.person.id).should_not be_mutual
end
it 'doesnt set mutual on a contact' do
pending
alice.receive_contact_request(@acceptance) alice.receive_contact_request(@acceptance)
Request.where(:sender_id => eve.person.id, :recipient_id => alice.person.id).should be_empty Request.where(:sender_id => eve.person.id, :recipient_id => alice.person.id).should be_empty
end end
@ -64,46 +74,65 @@ describe Diaspora::UserModules::Connecting do
describe 'disconnecting' do describe 'disconnecting' do
describe '#remove_contact' do describe '#remove_contact' do
it 'should remove the contact from all aspects they are in' do it 'removed non mutual contacts' do
contact = alice.contact_for(bob.person) alice.share_with(eve.person, alice.aspects.first)
new_aspect = alice.aspects.create(:name => 'new') lambda {
alice.add_contact_to_aspect( contact, new_aspect) alice.remove_contact alice.contact_for(eve.person)
}.should change {
lambda { alice.remove_contact(contact) }.should change( alice.contacts(true).count
contact.aspects, :count).from(2).to(0) }.by(-1)
end end
context 'with a post' do it 'removes a contacts mutual flag' do
lambda{
bob.remove_contact(bob.contact_for(alice.person))
}.should change {
bob.contacts.find_by_person_id(alice.person.id).mutual
}.from(true).to(false)
end
it "deletes the disconnected user's posts from visible_posts" do it "deletes the disconnected user's posts from visible_posts" do
StatusMessage.delete_all StatusMessage.delete_all
message = alice.post(:status_message, :text => "hi", :to => alice.aspects.first.id) message = alice.post(:status_message, :text => "hi", :to => alice.aspects.first.id)
bob.reload.raw_visible_posts.include?(message).should be_true bob.reload.raw_visible_posts.should include(message)
bob.disconnect bob.contact_for(alice.person) bob.disconnect bob.contact_for(alice.person)
bob.reload.raw_visible_posts.include?(message).should be_false bob.reload.raw_visible_posts.should_not include(message)
end end
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(true), :count).from(2).to(0)
end end
end end
describe '#disconnected_by' do describe '#disconnected_by' do
it 'removes a contacts mutual flag' do it 'calls remove contact' do
pending 'needs migration' bob.should_receive(:remove_contact).with(bob.contact_for(alice.person))
alice.share_with(eve.person, alice.aspects.first) bob.disconnected_by(alice.person)
alice.contacts.where(:person_id => eve.person.id).mutual.should be_true
eve.disconnected_by(alice.person)
alice.contacts.where(:person_id => eve.person.id).mutual.should be_false
end end
end end
describe '#disconnect' do describe '#disconnect' do
it 'disconnects a contact on the same seed' do it 'calls remove contact' do
bob.aspects.first.contacts.count.should == 2 contact = bob.contact_for(alice.person)
lambda {
bob.disconnect bob.contact_for(alice.person) }.should change { bob.should_receive(:remove_contact).with(contact)
bob.contacts(true).count }.by(-1) bob.disconnect contact
bob.aspects.first.contacts(true).count.should == 1 end
it 'dispatches a retraction' do
p = mock()
Postzord::Dispatch.should_receive(:new).and_return(p)
p.should_receive(:post)
bob.disconnect bob.contact_for(eve.person)
end end
end end
end end

View file

@ -48,13 +48,11 @@ describe User do
inviter.invite_user(aspect.id, 'email', @email).email.should == @email inviter.invite_user(aspect.id, 'email', @email).email.should == @email
end end
it "throws if you try to add someone you're connected to" do
it 'throws if you try to add someone you"re connected to' do
connect_users(inviter, aspect, another_user, wrong_aspect) connect_users(inviter, aspect, another_user, wrong_aspect)
inviter.reload
proc{ proc{
inviter.invite_user(aspect.id, 'email', another_user.email) inviter.invite_user(aspect.id, 'email', another_user.email)
}.should raise_error ActiveRecord::RecordInvalid }.should raise_error ActiveRecord::RecordNotUnique
end end
end end

View file

@ -13,11 +13,10 @@ describe User do
describe "#raw_visible_posts" do describe "#raw_visible_posts" do
it "returns all the posts the user can see" do it "returns all the posts the user can see" do
connect_users(eve, @eves_aspect, alice, @alices_aspect)
self_post = alice.post(:status_message, :text => "hi", :to => @alices_aspect.id) self_post = alice.post(:status_message, :text => "hi", :to => @alices_aspect.id)
visible_post = eve.post(:status_message, :text => "hello", :to => @eves_aspect.id) visible_post = bob.post(:status_message, :text => "hello", :to => bob.aspects.first.id)
dogs = eve.aspects.create(:name => "dogs") dogs = bob.aspects.create(:name => "dogs")
invisible_post = eve.post(:status_message, :text => "foobar", :to => dogs.id) invisible_post = bob.post(:status_message, :text => "foobar", :to => dogs.id)
stream = alice.raw_visible_posts stream = alice.raw_visible_posts
stream.should include(self_post) stream.should include(self_post)
@ -119,10 +118,6 @@ describe User do
end end
it "only returns non-pending contacts" do it "only returns non-pending contacts" do
alice.send_contact_request_to(Factory(:user).person, @alices_aspect)
@alices_aspect.reload
alice.reload
alice.people_in_aspects([@alices_aspect]).should == [bob.person] alice.people_in_aspects([@alices_aspect]).should == [bob.person]
end end

View file

@ -228,7 +228,7 @@ describe User do
end end
it "returns false if the user has already sent a request to that person" do it "returns false if the user has already sent a request to that person" do
alice.send_contact_request_to(eve.person, alice.aspects.first) alice.share_with(eve.person, alice.aspects.first)
alice.reload alice.reload
eve.reload eve.reload
alice.can_add?(eve.person).should be_false alice.can_add?(eve.person).should be_false
@ -332,22 +332,6 @@ describe User do
end end
end end
describe 'foreign key between aspects and contacts' do
it 'should delete an empty aspect' do
empty_aspect = alice.aspects.create(:name => 'decoy')
alice.aspects(true).include?(empty_aspect).should == true
empty_aspect.destroy
alice.aspects(true).include?(empty_aspect).should == false
end
it 'should not delete an aspect with contacts' do
aspect = alice.aspects.first
aspect.contacts.count.should > 0
proc { aspect.destroy }.should raise_error ActiveRecord::StatementInvalid
alice.aspects.include?(aspect).should == true
end
end
describe '#update_post' do describe '#update_post' do
it 'sends a notification to aspects' do it 'sends a notification to aspects' do
m = mock() m = mock()
@ -425,14 +409,18 @@ describe User do
it 'removes all contacts' do it 'removes all contacts' do
lambda { lambda {
alice.destroy alice.destroy
}.should change { alice.contacts(true).count }.by(-1) }.should change {
alice.contacts.count
}.by(-1)
end end
it 'removes all service connections' do it 'removes all service connections' do
Services::Facebook.create(:access_token => 'what', :user_id => alice.id) Services::Facebook.create(:access_token => 'what', :user_id => alice.id)
lambda { lambda {
alice.destroy alice.destroy
}.should change { alice.services(true).count }.by(-1) }.should change {
alice.services.count
}.by(-1)
end end
describe '#remove_person' do describe '#remove_person' do
@ -471,7 +459,7 @@ describe User do
end end
it 'has no error when the user has sent local requests' do it 'has no error when the user has sent local requests' do
alice.send_contact_request_to(eve.person, alice.aspects.first) alice.share_with(eve.person, alice.aspects.first)
lambda { lambda {
alice.destroy alice.destroy
}.should_not raise_error }.should_not raise_error

View file

@ -1,16 +1,10 @@
class User class User
def send_contact_request_to(desired_contact, aspect)
fantasy_resque do
contact = Contact.new(:person => desired_contact,
:user => self,
:pending => true)
contact.aspects << aspect
if contact.save! alias_method :share_with_original, :share_with
contact.dispatch_request
else def share_with(*args)
nil fantasy_resque do
end share_with_original(*args)
end end
end end