diff --git a/app/models/account_deletion.rb b/app/models/account_deletion.rb index 3c51e2a66..4ab5a5536 100644 --- a/app/models/account_deletion.rb +++ b/app/models/account_deletion.rb @@ -15,14 +15,17 @@ class AccountDeletion disassociate_invitations delete_mentions delete_contacts_of_me + remove_share_visibilities + remove_conversation_visibilities disconnect_contacts + delete_photos delete_posts tombstone_person_and_profile end #user deletions def normal_ar_user_associates_to_delete - [:tag_followings, :authorizations, :invitations_to_me, :services, :aspects, :user_preferences, :notifications] + [:tag_followings, :authorizations, :invitations_to_me, :services, :aspects, :user_preferences, :notifications, :blocks] end def special_ar_user_associations @@ -32,10 +35,10 @@ class AccountDeletion def ignored_ar_user_associations [:followed_tags, :invited_by, :contact_people, :applications, :aspect_memberships] end - + def delete_standard_associations normal_ar_user_associates_to_delete.each do |asso| - user.send(asso).delete_all + user.send(asso).destroy_all end end @@ -46,39 +49,28 @@ class AccountDeletion end def disconnect_contacts - user.contacts.delete_all + user.contacts.destroy_all end - - #person deletion -# def delete_posts -# end - -# def delete_photos -# end - -# def comments -# end - # def remove_share_visibilities - #my_contacts = user.contacts.map{|x| x.id} - #others_contacts = person.contacts{|x| x.id} - #ShareVisibility.where(:contact_id => my_contacts + others_contacts) + ShareVisibility.for_a_users_contacts(user).destroy_all + ShareVisibility.for_contacts_of_a_person(person).destroy_all end -# def delete_notification_actors -# end + def remove_conversation_visibilities + ConversationVisibility.where(:person_id => person.id).destroy_all + end def delete_posts - self.person.posts.delete_all + self.person.posts.destroy_all end def delete_photos - self.person.photos.delete_all + self.person.photos.destroy_all end def delete_mentions - self.person.mentions.delete_all + self.person.mentions.destroy_all end def tombstone_person_and_profile @@ -86,6 +78,6 @@ class AccountDeletion end def delete_contacts_of_me - Contact.all_contacts_of_person(self.person).delete_all + Contact.all_contacts_of_person(self.person).destroy_all end end diff --git a/app/models/share_visibility.rb b/app/models/share_visibility.rb index eb80309f4..b46fb3342 100644 --- a/app/models/share_visibility.rb +++ b/app/models/share_visibility.rb @@ -9,9 +9,9 @@ class ShareVisibility < ActiveRecord::Base scope :for_a_users_contacts, lambda { |user| where(:contact_id => user.contacts.map {|c| c.id}) } - - alias :for_a_users_contacts :for_contacts_of_a_person - + scope :for_contacts_of_a_person, lambda { |person| + where(:contact_id => person.contacts.map {|c| c.id}) + } # Perform a batch import, given a set of contacts and a shareable # @note performs a bulk insert in mySQL; performs linear insertions in postgres diff --git a/app/models/user.rb b/app/models/user.rb index e49025acd..269c00797 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -33,15 +33,15 @@ class User < ActiveRecord::Base has_one :person, :foreign_key => :owner_id delegate :public_key, :posts, :photos, :owns?, :diaspora_handle, :name, :public_url, :profile, :first_name, :last_name, :to => :person - has_many :invitations_from_me, :class_name => 'Invitation', :foreign_key => :sender_id, :dependent => :destroy - has_many :invitations_to_me, :class_name => 'Invitation', :foreign_key => :recipient_id, :dependent => :destroy + has_many :invitations_from_me, :class_name => 'Invitation', :foreign_key => :sender_id + has_many :invitations_to_me, :class_name => 'Invitation', :foreign_key => :recipient_id has_many :aspects, :order => 'order_id ASC' has_many :aspect_memberships, :through => :aspects has_many :contacts has_many :contact_people, :through => :contacts, :source => :person - has_many :services, :dependent => :destroy - has_many :user_preferences, :dependent => :destroy - has_many :tag_followings, :dependent => :destroy + has_many :services + has_many :user_preferences + has_many :tag_followings has_many :followed_tags, :through => :tag_followings, :source => :tag, :order => 'tags.name' has_many :blocks has_many :notifications, :foreign_key => :recipient_id diff --git a/spec/integration/account_deletion_spec.rb b/spec/integration/account_deletion_spec.rb index 053ace48b..13ccf1007 100644 --- a/spec/integration/account_deletion_spec.rb +++ b/spec/integration/account_deletion_spec.rb @@ -1,7 +1,7 @@ require 'spec_helper' describe 'deleteing your account' do - before do + before :all do @bob2 = bob @bobs_person_id = @bob2.person.id @alices_post = alice.post(:status_message, :text => "@{@bob2 Grimn; #{@bob2.person.diaspora_handle}} you are silly", :to => alice.aspects.find_by_name('generic')) @@ -19,8 +19,32 @@ describe 'deleteing your account' do #conversations create_conversation_with_message(alice, @bob2, "Subject", "Hey @bob2") - AccountDeletion.new(@bob2.person.diaspora_handle).perform! + #join tables + @users_sv = ShareVisibility.where(:contact_id => @bobs_contact_ids).all + @persons_sv = ShareVisibility.where(:contact_id => bob.person.contacts.map(&:id)).all + #user associated objects + @prefs = [] + %w{mentioned liked reshared}.each do |pref| + @prefs << @bob2.user_preferences.create!(:email_type => pref) + end + + # notifications + @notifications = [] + 3.times do |n| + @notifications << Factory(:notification, :recipient => @bob2) + end + + # services + @services = [] + 3.times do |n| + @services << Factory(:service, :user => @bob2) + end + + # block + @block = @bob2.blocks.create!(:person => eve.person) + + AccountDeletion.new(@bob2.person.diaspora_handle).perform! @bob2.reload end @@ -28,16 +52,32 @@ describe 'deleteing your account' do @bob2.posts.should be_empty end + it "deletes all of the user's preferences" do + UserPreference.where(:id => @prefs.map{|pref| pref.id}).should be_empty + end + + it "deletes all of the user's notifications" do + Notification.where(:id => @notifications.map{|n| n.id}).should be_empty + end + + it "deletes all of the users's blocked users" do + Block.where(:id => @block.id).should be_empty + end + + it "deletes all of the user's services" do + Service.where(:id => @services.map{|s| s.id}).should be_empty + end + it 'deletes all of @bob2s share visiblites' do - ShareVisibility.where(:contact_id => @bobs_contact_ids).should be_empty - ShareVisibility.where(:contact_id => bob.person.contacts.map(&:id)).should be_empty + ShareVisibility.where(:id => @users_sv.map{|sv| sv.id}).should be_empty + ShareVisibility.where(:id => @persons_sv.map{|sv| sv.id}).should be_empty end it 'deletes all photos' do Photo.where(:author_id => @bobs_person_id).should be_empty end - it 'deletes all mentions ' do + it 'deletes all mentions' do @bob2.person.mentions.should be_empty end @@ -55,7 +95,8 @@ describe 'deleteing your account' do @bob2.person.profile.reload.first_name.should be_blank end - it 'deletes the converersation visibilities' do - pending + it 'deletes only the converersation visibility for the deleted user' do + ConversationVisibility.where(:person_id => alice.person.id).should_not be_empty + ConversationVisibility.where(:person_id => bob.person.id).should be_empty end end diff --git a/spec/models/account_deletion_spec.rb b/spec/models/account_deletion_spec.rb index 9e4dc5c40..4b10fdcbf 100644 --- a/spec/models/account_deletion_spec.rb +++ b/spec/models/account_deletion_spec.rb @@ -16,48 +16,33 @@ describe AccountDeletion do end describe '#perform' do - it 'calls delete_standard_associations' do - @account_deletion.should_receive(:delete_standard_associations) + after do @account_deletion.perform! end - it 'calls disassociate_invitations' do - @account_deletion.should_receive(:disassociate_invitations) - @account_deletion.perform! - end + [:delete_standard_associations, + :disassociate_invitations, + :delete_standard_associations, + :delete_contacts_of_me, + :delete_mentions, + :disconnect_contacts, + :delete_photos, + :delete_posts, + :tombstone_person_and_profile, + :remove_share_visibilities, + :remove_conversation_visibilities].each do |method| - it 'calls delete_contacts_of_me' do - @account_deletion.should_receive(:delete_contacts_of_me) - @account_deletion.perform! - end - - it 'calls delete_contacts_of_me' do - @account_deletion.should_receive(:delete_mentions) - @account_deletion.perform! - end - - it 'calls disconnect_contacts' do - @account_deletion.should_receive(:disconnect_contacts) - @account_deletion.perform! - end - - it 'calls delete_posts' do - @account_deletion.should_receive(:delete_posts) - @account_deletion.perform! - end - - it 'calls tombstone_person_and_profile' do - @account_deletion.should_receive(:tombstone_person_and_profile) - @account_deletion.perform! + it "calls ##{method.to_s}" do + @account_deletion.should_receive(method) + end end end - + describe "#delete_standard_associations" do it 'removes all standard user associaltions' do - @account_deletion.normal_ar_user_associates_to_delete.each do |asso| association_mock = mock - association_mock.should_receive(:delete_all) + association_mock.should_receive(:destroy_all) bob.should_receive(asso).and_return(association_mock) end @@ -65,17 +50,16 @@ describe AccountDeletion do end end - describe '#delete_posts' do it 'deletes all posts' do - @account_deletion.person.posts.should_receive(:delete_all) + @account_deletion.person.posts.should_receive(:destroy_all) @account_deletion.delete_posts end end describe '#delete_photos' do it 'deletes all photos' do - @account_deletion.person.photos.should_receive(:delete_all) + @account_deletion.person.photos.should_receive(:destroy_all) @account_deletion.delete_photos end end @@ -89,26 +73,19 @@ describe AccountDeletion do end end - describe "#normal_ar_user_associates_to_delete" do - it "has the regular associations" do - @account_deletion.normal_ar_user_associates_to_delete.should == - [:tag_followings, :authorizations, :invitations_to_me, :services, :aspects, :user_preferences, :notifications] - end - end - context 'person associations' do describe '#delete mentions' do it 'deletes the mentions for people' do mentions = mock @account_deletion.person.should_receive(:mentions).and_return(mentions) - mentions.should_receive(:delete_all) + mentions.should_receive(:destroy_all) @account_deletion.delete_mentions end end describe '#disconnect_contacts' do it "deletes all of user's contacts" do - bob.contacts.should_receive(:delete_all) + bob.contacts.should_receive(:destroy_all) @account_deletion.disconnect_contacts end end @@ -117,7 +94,7 @@ describe AccountDeletion do it 'deletes all the local contact objects where deleted account is the person' do contacts = mock Contact.should_receive(:all_contacts_of_person).with(bob.person).and_return(contacts) - contacts.should_receive(:delete_all) + contacts.should_receive(:destroy_all) @account_deletion.delete_contacts_of_me end end @@ -128,6 +105,40 @@ describe AccountDeletion do @account_deletion.tombstone_person_and_profile end end + describe "#remove_conversation_visibilities" do + it "removes the conversation visibility for the deleted user" do + vis = stub + ConversationVisibility.should_receive(:where).with(hash_including(:person_id => bob.person.id)).and_return(vis) + vis.should_receive(:destroy_all) + @account_deletion.remove_conversation_visibilities + end + end + end + + describe "#remove_share_visibilities" do + before do + @s_vis = stub + end + + after do + @account_deletion.remove_share_visibilities + end + + it 'removes the share visibilities for a person ' do + ShareVisibility.should_receive(:for_contacts_of_a_person).with(bob.person).and_return(@s_vis) + @s_vis.should_receive(:destroy_all) + end + + it 'removes the share visibilities for a user' do + ShareVisibility.should_receive(:for_a_users_contacts).with(bob).and_return(@s_vis) + @s_vis.should_receive(:destroy_all) + end + + it 'does not remove share visibilities for a user if the user is not present' do + pending + ShareVisibility.should_receive(:for_a_users_contacts).with(bob).and_return(@s_vis) + @s_vis.should_receive(:destroy_all) + end end it 'has all user association keys accounted for' do