From 102e2a083424c66f0b6cbceb019e6bb2ea7b694a Mon Sep 17 00:00:00 2001 From: Benjamin Neff Date: Mon, 16 May 2016 19:39:43 +0200 Subject: [PATCH] remove Request class and refactor Connecting --- app/models/contact.rb | 73 ++++----- app/models/user/connecting.rb | 85 +++++----- lib/diaspora/federated.rb | 3 +- lib/diaspora/federated/request.rb | 86 ---------- lib/postzord/receiver/private.rb | 11 +- spec/integration/receiving_spec.rb | 2 +- spec/lib/diaspora/federated/request_spec.rb | 93 ----------- spec/models/contact_spec.rb | 120 ++++++-------- spec/models/user/connecting_spec.rb | 172 +++++++++++--------- 9 files changed, 216 insertions(+), 429 deletions(-) delete mode 100644 lib/diaspora/federated/request.rb delete mode 100644 spec/lib/diaspora/federated/request_spec.rb diff --git a/app/models/contact.rb b/app/models/contact.rb index 055b6ed4e..6480d2627 100644 --- a/app/models/contact.rb +++ b/app/models/contact.rb @@ -4,57 +4,44 @@ class Contact < ActiveRecord::Base belongs_to :user + validates :user, presence: true belongs_to :person - validates :person, :presence => true + validates :person, presence: true + + validates :person_id, uniqueness: {scope: :user_id} delegate :name, :diaspora_handle, :guid, :first_name, to: :person, prefix: true - has_many :aspect_memberships, :dependent => :destroy - has_many :aspects, :through => :aspect_memberships + has_many :aspect_memberships, dependent: :destroy + has_many :aspects, through: :aspect_memberships validate :not_contact_for_self, :not_blocked_user, :not_contact_with_closed_account - validates_presence_of :user - validates_uniqueness_of :person_id, :scope => :user_id - before_destroy :destroy_notifications - scope :all_contacts_of_person, ->(x) { where(:person_id => x.id) } + scope :all_contacts_of_person, ->(x) { where(person_id: x.id) } - # contact.sharing is true when contact.person is sharing with contact.user - scope :sharing, -> { where(:sharing => true) } + # contact.sharing is true when contact.person is sharing with contact.user + scope :sharing, -> { where(sharing: true) } # contact.receiving is true when contact.user is sharing with contact.person - scope :receiving, -> { where(:receiving => true) } + scope :receiving, -> { where(receiving: true) } - scope :for_a_stream, -> { - includes(:aspects, :person => :profile). - order('profiles.last_name ASC') - } + scope :for_a_stream, -> { includes(:aspects, person: :profile).order("profiles.last_name ASC") } - scope :only_sharing, -> { sharing.where(:receiving => false) } + scope :only_sharing, -> { sharing.where(receiving: false) } def destroy_notifications - Notification.where(:target_type => "Person", - :target_id => person_id, - :recipient_id => user_id, - :type => "Notifications::StartedSharing").destroy_all - end - - def dispatch_request - request = self.generate_request - Postzord::Dispatcher.build(self.user, request).post - request - end - - def generate_request - Request.diaspora_initialize(:from => self.user.person, - :to => self.person, - :into => aspects.first) + Notification.where( + target_type: "Person", + target_id: person_id, + recipient_id: user_id, + type: "Notifications::StartedSharing" + ).destroy_all end def contacts @@ -69,10 +56,10 @@ class Contact < ActiveRecord::Base end def mutual? - self.sharing && self.receiving + sharing && receiving end - def in_aspect? aspect + def in_aspect?(aspect) if aspect_memberships.loaded? aspect_memberships.detect{ |am| am.aspect_id == aspect.id } elsif aspects.loaded? @@ -98,27 +85,23 @@ class Contact < ActiveRecord::Base user.share_with(person, user.auto_follow_back_aspect) if user.auto_follow_back && !receiving end + # @return [Array] The recipient of the contact + def subscribers + [person] + end + private def not_contact_with_closed_account - if person_id && person.closed_account? - errors[:base] << 'Cannot be in contact with a closed account' - end + errors.add(:base, "Cannot be in contact with a closed account") if person_id && person.closed_account? end def not_contact_for_self - if person_id && person.owner == user - errors[:base] << 'Cannot create self-contact' - end + errors.add(:base, "Cannot create self-contact") if person_id && person.owner == user end def not_blocked_user - if user && user.blocks.where(:person_id => person_id).exists? - errors[:base] << 'Cannot connect to an ignored user' - false - else - true - end + errors.add(:base, "Cannot connect to an ignored user") if user && user.blocks.where(person_id: person_id).exists? end end diff --git a/app/models/user/connecting.rb b/app/models/user/connecting.rb index a1f425206..238b06199 100644 --- a/app/models/user/connecting.rb +++ b/app/models/user/connecting.rb @@ -2,56 +2,55 @@ # licensed under the Affero General Public License version 3 or later. See # the COPYRIGHT file. -module User::Connecting - # This will create a contact on the side of the sharer and the sharee. - # @param [Person] person The person to start sharing with. - # @param [Aspect] aspect The aspect to add them to. - # @return [Contact] The newly made contact for the passed in person. - def share_with(person, aspect) - contact = self.contacts.find_or_initialize_by(person_id: person.id) - return false unless contact.valid? +class User + module Connecting + # This will create a contact on the side of the sharer and the sharee. + # @param [Person] person The person to start sharing with. + # @param [Aspect] aspect The aspect to add them to. + # @return [Contact] The newly made contact for the passed in person. + def share_with(person, aspect) + contact = contacts.find_or_initialize_by(person_id: person.id) + return false unless contact.valid? - unless contact.receiving? - contact.dispatch_request - contact.receiving = true + unless contact.receiving? + # TODO: dispatch + contact.receiving = true + end + + contact.aspects << aspect + contact.save + + Notifications::StartedSharing.where(recipient_id: id, target: person.id, unread: true) + .update_all(unread: false) + + deliver_profile_update + contact end - contact.aspects << aspect - contact.save + def disconnect(contact, opts={force: false}) + logger.info "event=disconnect user=#{diaspora_handle} target=#{contact.person.diaspora_handle}" - if notification = Notification.where(:target_id => person.id).first - notification.update_attributes(:unread=>false) + # TODO: send retraction + + contact.aspect_memberships.delete_all + + if !contact.sharing || opts[:force] + contact.destroy + else + contact.update_attributes(receiving: false) + end end - deliver_profile_update - contact - end + def disconnected_by(person) + logger.info "event=disconnected_by user=#{diaspora_handle} target=#{person.diaspora_handle}" + contact = contact_for(person) + return unless contact - def remove_contact(contact, opts={:force => false, :retracted => false}) - if !contact.mutual? || opts[:force] - contact.destroy - elsif opts[:retracted] - contact.update_attributes(:sharing => false) - else - contact.update_attributes(:receiving => false) - end - end - - def disconnect(bad_contact, opts={}) - person = bad_contact.person - logger.info "event=disconnect user=#{diaspora_handle} target=#{person.diaspora_handle}" - retraction = Retraction.for(self) - retraction.subscribers = [person]#HAX - Postzord::Dispatcher.build(self, retraction).post - - AspectMembership.where(:contact_id => bad_contact.id).delete_all - remove_contact(bad_contact, opts) - end - - def disconnected_by(person) - logger.info "event=disconnected_by user=#{diaspora_handle} target=#{person.diaspora_handle}" - if contact = self.contact_for(person) - remove_contact(contact, :retracted => true) + if contact.receiving + contact.update_attributes(sharing: false) + else + contact.destroy + end end end end diff --git a/lib/diaspora/federated.rb b/lib/diaspora/federated.rb index b554d2b71..edc471617 100644 --- a/lib/diaspora/federated.rb +++ b/lib/diaspora/federated.rb @@ -4,9 +4,8 @@ module Diaspora module Federated - require 'diaspora/federated/request' require 'diaspora/federated/retraction' require 'diaspora/federated/signed_retraction' require 'diaspora/federated/relayable_retraction' end -end \ No newline at end of file +end diff --git a/lib/diaspora/federated/request.rb b/lib/diaspora/federated/request.rb deleted file mode 100644 index bb82514fe..000000000 --- a/lib/diaspora/federated/request.rb +++ /dev/null @@ -1,86 +0,0 @@ -# Copyright (c) 2010-2011, Diaspora Inc. This file is -# t -# licensed under the Affero General Public License version 3 or later. See -# the COPYRIGHT file. - -class Request - include Diaspora::Federated::Base - include ActiveModel::Validations - - attr_accessor :sender, :recipient, :aspect - - xml_accessor :sender_handle - xml_accessor :recipient_handle - - validates :sender, :presence => true - validates :recipient, :presence => true - - validate :not_already_connected - validate :not_friending_yourself - - # Initalize variables - # @note we should be using ActiveModel::Serialization for this - # @return [Request] - def self.diaspora_initialize(opts = {}) - req = self.new - req.sender = opts[:from] - req.recipient = opts[:to] - req.aspect = opts[:into] - req - end - - # Alias of sender_handle - # @return [String] - def diaspora_handle - sender_handle - end - - # @note Used for XML marshalling - # @return [String] - def sender_handle - sender.diaspora_handle - end - def sender_handle= sender_handle - self.sender = Person.where(:diaspora_handle => sender_handle).first - end - - # @note Used for XML marshalling - # @return [String] - def recipient_handle - recipient.diaspora_handle - end - def recipient_handle= recipient_handle - self.recipient = Person.where(:diaspora_handle => recipient_handle).first - end - - # Defines the abstract interface used in sending a corresponding [Notification] given the [Request] - # @param user [User] - # @param person [Person] - # @return [Notifications::StartedSharing] - def notification_type(user, person) - Notifications::StartedSharing - end - - # Defines the abstract interface used in sending the [Request] - # @param user [User] - # @return [Array] The recipient of the request - def subscribers(user) - [self.recipient] - end - - private - - # Checks if a [Contact] does not already exist between the requesting [User] and receiving [Person] - def not_already_connected - if sender && recipient && Contact.where(:user_id => self.recipient.owner_id, :person_id => self.sender.id).exists? - errors[:base] << 'You have already connected to this person' - end - end - - # Checks to see that the requesting [User] is not sending a request to himself - def not_friending_yourself - if self.recipient == self.sender - errors[:base] << 'You can not friend yourself' - end - end -end diff --git a/lib/postzord/receiver/private.rb b/lib/postzord/receiver/private.rb index 2ed351d29..f871b4035 100644 --- a/lib/postzord/receiver/private.rb +++ b/lib/postzord/receiver/private.rb @@ -79,23 +79,14 @@ class Postzord::Receiver::Private < Postzord::Receiver raise Diaspora::ContactRequiredUnlessRequest if contact_required_unless_request raise Diaspora::RelayableObjectWithoutParent if relayable_without_parent? - assign_sender_handle_if_request - raise Diaspora::AuthorXMLAuthorMismatch if author_does_not_match_xml_author? end def contact_required_unless_request - unless @object.is_a?(Request) || @user.contact_for(@author) || (@author.owner && @author.owner.podmin_account?) + unless @user.contact_for(@author) || (@author.owner && @author.owner.podmin_account?) logger.error "event=receive status=abort reason='sender not connected to recipient' type=#{@object.class} " \ "recipient=#{@user_person.diaspora_handle} sender=#{@author.diaspora_handle}" return true end end - - def assign_sender_handle_if_request - #special casey - if @object.is_a?(Request) - @object.sender_handle = @author.diaspora_handle - end - end end diff --git a/spec/integration/receiving_spec.rb b/spec/integration/receiving_spec.rb index 451a29e77..f927c35cf 100644 --- a/spec/integration/receiving_spec.rb +++ b/spec/integration/receiving_spec.rb @@ -45,7 +45,7 @@ describe 'a user receives a post', :type => :request do end it "does not remove visibility on disconnect" do - alice.remove_contact(alice.contact_for(bob.person), force: true) + alice.disconnect(alice.contact_for(bob.person), force: true) alice.reload expect(ShareVisibility.find_by(user_id: alice.id, shareable_id: @status_message.id)).not_to be_nil end diff --git a/spec/lib/diaspora/federated/request_spec.rb b/spec/lib/diaspora/federated/request_spec.rb deleted file mode 100644 index c92666baa..000000000 --- a/spec/lib/diaspora/federated/request_spec.rb +++ /dev/null @@ -1,93 +0,0 @@ -# Copyright (c) 2010-2011, Diaspora Inc. This file is -# licensed under the Affero General Public License version 3 or later. See -# the COPYRIGHT file. - -require 'spec_helper' - -describe Request do - before do - @aspect = alice.aspects.first - end - - describe 'validations' do - before do - @request = described_class.diaspora_initialize(:from => alice.person, :to => eve.person, :into => @aspect) - end - - it 'is valid' do - expect(@request.sender).to eq(alice.person) - expect(@request.recipient).to eq(eve.person) - expect(@request.aspect).to eq(@aspect) - expect(@request).to be_valid - end - - it 'is from a person' do - @request.sender = nil - expect(@request).not_to be_valid - end - - it 'is to a person' do - @request.recipient = nil - expect(@request).not_to be_valid - end - - it 'is not necessarily into an aspect' do - @request.aspect = nil - expect(@request).to be_valid - end - - it 'is not from an existing friend' do - Contact.create(:user => eve, :person => alice.person, :aspects => [eve.aspects.first]) - expect(@request).not_to be_valid - end - - it 'is not to yourself' do - @request = described_class.diaspora_initialize(:from => alice.person, :to => alice.person, :into => @aspect) - expect(@request).not_to be_valid - end - end - - describe '#notification_type' do - it 'returns request_accepted' do - person = FactoryGirl.build:person - - request = described_class.diaspora_initialize(:from => alice.person, :to => eve.person, :into => @aspect) - alice.contacts.create(:person_id => person.id) - - expect(request.notification_type(alice, person)).to eq(Notifications::StartedSharing) - end - end - - describe '#subscribers' do - it 'returns an array with to field on a request' do - request = described_class.diaspora_initialize(:from => alice.person, :to => eve.person, :into => @aspect) - expect(request.subscribers(alice)).to match_array([eve.person]) - end - end - - context 'xml' do - before do - @request = described_class.diaspora_initialize(:from => alice.person, :to => eve.person, :into => @aspect) - @xml = @request.to_xml.to_s - end - - describe 'serialization' do - it 'produces valid xml' do - expect(@xml).to include alice.person.diaspora_handle - expect(@xml).to include eve.person.diaspora_handle - expect(@xml).not_to include alice.person.exported_key - expect(@xml).not_to include alice.person.profile.first_name - end - end - - context 'marshalling' do - it 'produces a request object' do - marshalled = described_class.from_xml @xml - - expect(marshalled.sender).to eq(alice.person) - expect(marshalled.recipient).to eq(eve.person) - expect(marshalled.aspect).to be_nil - end - end - end -end diff --git a/spec/models/contact_spec.rb b/spec/models/contact_spec.rb index 390ee776a..522413003 100644 --- a/spec/models/contact_spec.rb +++ b/spec/models/contact_spec.rb @@ -4,7 +4,7 @@ require "spec_helper" -describe Contact, :type => :model do +describe Contact, type: :model do describe "aspect_memberships" do it "deletes dependent aspect memberships" do expect { @@ -16,6 +16,10 @@ describe Contact, :type => :model do context "validations" do let(:contact) { Contact.new } + it "is valid" do + expect(alice.contact_for(bob.person)).to be_valid + end + it "requires a user" do contact.valid? expect(contact.errors.full_messages).to include "User can't be blank" @@ -26,31 +30,46 @@ describe Contact, :type => :model do expect(contact.errors.full_messages).to include "Person can't be blank" end - it "ensures user is not making a contact for himself" do - contact.person = alice.person - contact.user = alice - - contact.valid? - expect(contact.errors.full_messages).to include "Cannot create self-contact" - end - it "validates uniqueness" do person = FactoryGirl.create(:person) - contact2 = alice.contacts.create(person: person) - expect(contact2).to be_valid + contact1 = alice.contacts.create(person: person) + expect(contact1).to be_valid - contact.user = alice - contact.person = person - expect(contact).not_to be_valid + contact2 = alice.contacts.create(person: person) + expect(contact2).not_to be_valid end - it "validates that the person's account is not closed" do - person = FactoryGirl.create(:person, :closed_account => true) - contact = alice.contacts.new(person: person) + describe "#not_contact_with_closed_account" do + it "adds error if the person's account is closed" do + person = FactoryGirl.create(:person, closed_account: true) + bad_contact = alice.contacts.create(person: person) - expect(contact).not_to be_valid - expect(contact.errors.full_messages).to include "Cannot be in contact with a closed account" + expect(bad_contact).not_to be_valid + expect(bad_contact.errors.full_messages.count).to eq(1) + expect(bad_contact.errors.full_messages.first).to eq("Cannot be in contact with a closed account") + end + end + + describe "#not_contact_for_self" do + it "adds error contacting self" do + bad_contact = alice.contacts.create(person: alice.person) + + expect(bad_contact).not_to be_valid + expect(bad_contact.errors.full_messages.count).to eq(1) + expect(bad_contact.errors.full_messages.first).to eq("Cannot create self-contact") + end + end + + describe "#not_blocked_user" do + it "add error if potential contact is blocked by user" do + alice.blocks.create(person: eve.person) + bad_contact = alice.contacts.create(person: eve.person) + + expect(bad_contact).not_to be_valid + expect(bad_contact.errors.full_messages.count).to eq(1) + expect(bad_contact.errors.full_messages.first).to eq("Cannot connect to an ignored user") + end end end @@ -60,7 +79,7 @@ describe Contact, :type => :model do expect { alice.contacts.create!(sharing: true, person: FactoryGirl.create(:person)) alice.contacts.create!(sharing: false, person: FactoryGirl.create(:person)) - }.to change{ + }.to change { Contact.sharing.count }.by(1) end @@ -71,7 +90,7 @@ describe Contact, :type => :model do expect { alice.contacts.create!(receiving: true, person: FactoryGirl.build(:person)) alice.contacts.create!(receiving: false, person: FactoryGirl.build(:person)) - }.to change{ + }.to change { Contact.receiving.count }.by(1) end @@ -84,7 +103,7 @@ describe Contact, :type => :model do alice.contacts.create!(receiving: false, sharing: true, person: FactoryGirl.build(:person)) alice.contacts.create!(receiving: false, sharing: true, person: FactoryGirl.build(:person)) alice.contacts.create!(receiving: true, sharing: false, person: FactoryGirl.build(:person)) - }.to change{ + }.to change { Contact.receiving.count }.by(2) end @@ -93,10 +112,11 @@ describe Contact, :type => :model do describe "all_contacts_of_person" do it "returns all contacts where the person is the passed in person" do person = FactoryGirl.create(:person) + contact1 = FactoryGirl.create(:contact, person: person) - contact2 = FactoryGirl.create(:contact) - contacts = Contact.all_contacts_of_person(person) - expect(contacts).to eq([contact1]) + FactoryGirl.create(:contact) # contact2 + + expect(Contact.all_contacts_of_person(person)).to eq([contact1]) end end end @@ -122,7 +142,7 @@ describe Contact, :type => :model do bob.contacts.create(person: person, aspects: [@new_aspect]) @people2 << person end - #eve <-> bob <-> alice + # eve <-> bob <-> alice end context "on a contact for a local user" do @@ -158,32 +178,6 @@ describe Contact, :type => :model do end end - context "requesting" do - let(:contact) { Contact.new user: user, person: person } - let(:user) { build(:user) } - let(:person) { build(:person) } - - describe "#generate_request" do - it "makes a request" do - allow(contact).to receive(:user).and_return(user) - request = contact.generate_request - - expect(request.sender).to eq(user.person) - expect(request.recipient).to eq(person) - end - end - - describe "#dispatch_request" do - it "pushes to people" do - allow(contact).to receive(:user).and_return(user) - m = double() - expect(m).to receive(:post) - expect(Postzord::Dispatcher).to receive(:build).and_return(m) - contact.dispatch_request - end - end - end - describe "#receive" do it "shares back if auto_following is enabled" do alice.auto_follow_back = true @@ -216,24 +210,10 @@ describe Contact, :type => :model do end end - describe "#not_blocked_user" do - let(:contact) { alice.contact_for(bob.person) } - - it "is called on validate" do - expect(contact).to receive(:not_blocked_user) - contact.valid? - end - - it "adds to errors if potential contact is blocked by user" do - person = eve.person - alice.blocks.create(person: person) - bad_contact = alice.contacts.create(person: person) - - expect(bad_contact.send(:not_blocked_user)).to be false - end - - it "does not add to errors" do - expect(contact.send(:not_blocked_user)).to be true + describe "#subscribers" do + it "returns an array with recipient of the contact" do + contact = alice.contacts.create(person: eve.person) + expect(contact.subscribers).to match_array([eve.person]) end end end diff --git a/spec/models/user/connecting_spec.rb b/spec/models/user/connecting_spec.rb index f4f178099..24afe624f 100644 --- a/spec/models/user/connecting_spec.rb +++ b/spec/models/user/connecting_spec.rb @@ -2,80 +2,92 @@ # licensed under the Affero General Public License version 3 or later. See # the COPYRIGHT file. -require 'spec_helper' +require "spec_helper" -describe User::Connecting, :type => :model do +describe User::Connecting, type: :model do + let(:aspect1) { alice.aspects.first } + let(:aspect2) { alice.aspects.create(name: "other") } - let(:aspect) { alice.aspects.first } - let(:aspect1) { alice.aspects.create(:name => 'other') } let(:person) { FactoryGirl.create(:person) } - let(:aspect2) { eve.aspects.create(:name => "aspect two") } + describe "disconnecting" do + describe "#disconnected_by" do + it "removes contact sharing flag" do + expect(bob.contacts.find_by(person_id: alice.person.id)).to be_sharing + bob.disconnected_by(alice.person) + expect(bob.contacts.find_by(person_id: alice.person.id)).not_to be_sharing + end - let(:person_one) { FactoryGirl.create :person } - let(:person_two) { FactoryGirl.create :person } - let(:person_three) { FactoryGirl.create :person } + it "removes contact if not receiving" do + eve.contacts.create(person: alice.person) - describe 'disconnecting' do - describe '#remove_contact' do - it 'removed non mutual contacts' do - alice.share_with(eve.person, alice.aspects.first) expect { - alice.remove_contact alice.contact_for(eve.person) - }.to change { - alice.contacts(true).count - }.by(-1) + eve.disconnected_by(alice.person) + }.to change(eve.contacts(true), :count).by(-1) end - it 'removes a contacts receiving flag' do - expect(bob.contacts.find_by_person_id(alice.person.id)).to be_receiving - bob.remove_contact(bob.contact_for(alice.person)) - expect(bob.contacts(true).find_by_person_id(alice.person.id)).not_to be_receiving - end - end + it "does not remove contact if disconnect twice" do + contact = bob.contact_for(alice.person) + expect(contact).to be_receiving - describe '#disconnected_by' do - it 'calls remove contact' do - expect(bob).to receive(:remove_contact).with(bob.contact_for(alice.person), :retracted => true) - bob.disconnected_by(alice.person) + expect { + bob.disconnected_by(alice.person) + bob.disconnected_by(alice.person) + }.not_to change(bob.contacts(true), :count) + + contact.reload + expect(contact).not_to be_sharing + expect(contact).to be_receiving end - it 'removes contact sharing flag' do - expect(bob.contacts.find_by_person_id(alice.person.id)).to be_sharing - bob.disconnected_by(alice.person) - expect(bob.contacts.find_by_person_id(alice.person.id)).not_to be_sharing - end - - it 'removes notitications' do + it "removes notitications" do skip # TODO alice.share_with(eve.person, alice.aspects.first) - expect(Notifications::StartedSharing.where(:recipient_id => eve.id).first).not_to be_nil + expect(Notifications::StartedSharing.where(recipient_id: eve.id).first).not_to be_nil eve.disconnected_by(alice.person) - expect(Notifications::StartedSharing.where(:recipient_id => eve.id).first).to be_nil + expect(Notifications::StartedSharing.where(recipient_id: eve.id).first).to be_nil end end - describe '#disconnect' do - it 'calls remove contact' do - contact = bob.contact_for(alice.person) - - expect(bob).to receive(:remove_contact).with(contact, {}) - bob.disconnect(contact) + describe "#disconnect" do + it "removes a contacts receiving flag" do + expect(bob.contacts.find_by(person_id: alice.person.id)).to be_receiving + bob.disconnect(bob.contact_for(alice.person)) + expect(bob.contacts(true).find_by(person_id: alice.person.id)).not_to be_receiving end - it 'dispatches a retraction' do - p = double() - expect(Postzord::Dispatcher).to receive(:build).and_return(p) - expect(p).to receive(:post) + it "removes contact if not sharing" do + contact = alice.share_with(eve.person, alice.aspects.first) + + expect { + alice.disconnect(contact) + }.to change(alice.contacts(true), :count).by(-1) + end + + it "does not remove contact if disconnect twice" do + contact = bob.contact_for(alice.person) + expect(contact).to be_sharing + + expect { + alice.disconnect(contact) + alice.disconnect(contact) + }.not_to change(bob.contacts(true), :count) + + contact.reload + expect(contact).not_to be_receiving + expect(contact).to be_sharing + end + + it "dispatches a retraction" do + skip # TODO bob.disconnect bob.contact_for(eve.person) end - it 'should remove the contact from all aspects they are in' 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) + alice.add_contact_to_aspect(contact, aspect2) expect { alice.disconnect(contact) @@ -84,28 +96,28 @@ describe User::Connecting, :type => :model do end end - describe '#share_with' do - it 'finds or creates a contact' do + describe "#share_with" do + it "finds or creates a contact" do expect { alice.share_with(eve.person, alice.aspects.first) }.to change(alice.contacts, :count).by(1) end - it 'does not set mutual on intial share request' do + it "does not set mutual on intial share request" do alice.share_with(eve.person, alice.aspects.first) - expect(alice.contacts.find_by_person_id(eve.person.id)).not_to be_mutual + expect(alice.contacts.find_by(person_id: eve.person.id)).not_to be_mutual end - it 'does set mutual on share-back request' do + it "does set mutual on share-back request" do skip # TODO eve.share_with(alice.person, eve.aspects.first) alice.share_with(eve.person, alice.aspects.first) - expect(alice.contacts.find_by_person_id(eve.person.id)).to be_mutual + expect(alice.contacts.find_by(person_id: eve.person.id)).to be_mutual end - it 'adds a contact to an aspect' do - contact = alice.contacts.create(:person => eve.person) + it "adds a contact to an aspect" do + contact = alice.contacts.create(person: eve.person) allow(alice.contacts).to receive(:find_or_initialize_by).and_return(contact) expect { @@ -113,55 +125,57 @@ describe User::Connecting, :type => :model do }.to change(contact.aspects, :count).by(1) end - context 'dispatching' do - it 'dispatches a request on initial request' do - contact = alice.contacts.new(:person => eve.person) - allow(alice.contacts).to receive(:find_or_initialize_by).and_return(contact) + context "dispatching" do + it "dispatches a request on initial request" do + skip # TODO + + contact = alice.contacts.new(person: eve.person) + expect(alice.contacts).to receive(:find_or_initialize_by).and_return(contact) + + # TODO: expect(contact).to receive(:dispatch_request) - expect(contact).to receive(:dispatch_request) alice.share_with(eve.person, alice.aspects.first) end - it 'dispatches a request on a share-back' do + it "dispatches a request on a share-back" do skip # TODO + eve.share_with(alice.person, eve.aspects.first) contact = alice.contact_for(eve.person) - allow(alice.contacts).to receive(:find_or_initialize_by).and_return(contact) + expect(alice.contacts).to receive(:find_or_initialize_by).and_return(contact) + + # TODO: expect(contact).to receive(:dispatch_request) - expect(contact).to receive(:dispatch_request) alice.share_with(eve.person, alice.aspects.first) end - it 'does not dispatch a request if contact already marked as receiving' do - a2 = alice.aspects.create(:name => "two") - - contact = alice.contacts.create(:person => eve.person, :receiving => true) + it "does not dispatch a request if contact already marked as receiving" do + contact = alice.contacts.create(person: eve.person, receiving: true) allow(alice.contacts).to receive(:find_or_initialize_by).and_return(contact) - expect(contact).not_to receive(:dispatch_request) - alice.share_with(eve.person, a2) + # TODO: expect(contact).not_to receive(:dispatch_request) + + alice.share_with(eve.person, aspect2) end - it 'posts profile' do - m = double() - expect(Postzord::Dispatcher).to receive(:build).twice.and_return(m) - expect(m).to receive(:post).twice + it "posts profile" do + skip # TODO alice.share_with(eve.person, alice.aspects.first) end end - it 'sets receiving' do + it "sets receiving" do alice.share_with(eve.person, alice.aspects.first) expect(alice.contact_for(eve.person)).to be_receiving end it "should mark the corresponding notification as 'read'" do - notification = FactoryGirl.create(:notification, :target => eve.person) + FactoryGirl.create(:notification, target: eve.person, recipient: alice, type: "Notifications::StartedSharing") + expect(Notifications::StartedSharing.find_by(recipient_id: alice.id, target: eve.person).unread).to be_truthy - expect(Notification.where(:target_id => eve.person.id).first.unread).to be true - alice.share_with(eve.person, aspect) - expect(Notification.where(:target_id => eve.person.id).first.unread).to be false + alice.share_with(eve.person, aspect1) + expect(Notifications::StartedSharing.find_by(recipient_id: alice.id, target: eve.person).unread).to be_falsey end end end