From 7db4f825a6a7901a345e85fb0a1cda49722b922b Mon Sep 17 00:00:00 2001 From: cmrd Senya Date: Thu, 13 Apr 2017 19:20:55 +0300 Subject: [PATCH] Refactor account deletion spec This commit refactors account deletion spec by moving data creation to a helper object DataGenerator. --- spec/factories.rb | 5 + spec/helper_methods.rb | 10 +- spec/integration/account_deletion_spec.rb | 160 ++++++---------------- spec/misc_spec.rb | 2 +- spec/shared_behaviors/account_deletion.rb | 47 +++---- spec/support/data_generator.rb | 122 +++++++++++++++++ 6 files changed, 193 insertions(+), 153 deletions(-) create mode 100644 spec/support/data_generator.rb diff --git a/spec/factories.rb b/spec/factories.rb index fadc1d172..1f5f59d2e 100644 --- a/spec/factories.rb +++ b/spec/factories.rb @@ -342,6 +342,11 @@ FactoryGirl.define do additional_data { {"new_property" => "some text"} } end + factory :role do + association :person + name "moderator" + end + factory(:poll_participation_signature) do author_signature "some signature" association :signature_order, order: "guid parent_guid author poll_answer_guid new_property" diff --git a/spec/helper_methods.rb b/spec/helper_methods.rb index f7406a3ef..720f28058 100644 --- a/spec/helper_methods.rb +++ b/spec/helper_methods.rb @@ -27,12 +27,12 @@ module HelperMethods File.open(fixture_name) end - def create_conversation_with_message(sender, recipient_person, subject, text) + def create_conversation_with_message(sender_person, recipient_person, subject, text) create_hash = { - :author => sender.person, - :participant_ids => [sender.person.id, recipient_person.id], - :subject => subject, - :messages_attributes => [ {:author => sender.person, :text => text} ] + author: sender_person, + participant_ids: [sender_person.id, recipient_person.id], + subject: subject, + messages_attributes: [{author: sender_person, text: text}] } Conversation.create!(create_hash) diff --git a/spec/integration/account_deletion_spec.rb b/spec/integration/account_deletion_spec.rb index dfe3ee7c0..7c9346204 100644 --- a/spec/integration/account_deletion_spec.rb +++ b/spec/integration/account_deletion_spec.rb @@ -1,128 +1,46 @@ -describe "deleteing your account", type: :request do - context "user" do - before do - @person = bob.person - @alices_post = alice.post(:status_message, - text: "@{bob Grimn; #{bob.person.diaspora_handle}} you are silly", - to: alice.aspects.find_by_name("generic")) - - # bob's own content - bob.post(:status_message, text: "asldkfjs", to: bob.aspects.first) - FactoryGirl.create(:photo, author: bob.person) - - @aspect_vis = AspectVisibility.where(aspect_id: bob.aspects.map(&:id)) - - # objects on post - bob.like!(@alices_post) - bob.comment!(@alices_post, "here are some thoughts on your post") - - # conversations - create_conversation_with_message(alice, bob.person, "Subject", "Hey bob") - - # join tables - @users_sv = ShareVisibility.where(user_id: bob.id).load - @persons_sv = ShareVisibility.where(shareable_id: bob.posts.map(&:id), shareable_type: "Post").load - - # user associated objects - @prefs = [] - %w(mentioned liked reshared).each do |pref| - @prefs << bob.user_preferences.create!(email_type: pref) - end - - # notifications - @notifications = [] - 3.times do - @notifications << FactoryGirl.create(:notification, recipient: bob) - end - - # services - @services = [] - 3.times do - @services << FactoryGirl.create(:service, user: bob) - end - - # block - @block = bob.blocks.create!(person: eve.person) - - AccountDeleter.new(bob.person.diaspora_handle).perform! - bob.reload - end - - it "deletes all of the user's preferences" do - expect(UserPreference.where(id: @prefs.map(&:id))).to be_empty - end - - it "deletes all of the user's notifications" do - expect(Notification.where(id: @notifications.map(&:id))).to be_empty - end - - it "deletes all of the users's blocked users" do - expect(Block.where(id: @block.id)).to be_empty - end - - it "deletes all of the user's services" do - expect(Service.where(id: @services.map(&:id))).to be_empty - end - - it "deletes all of bobs share visiblites" do - expect(ShareVisibility.where(id: @users_sv.map(&:id))).to be_empty - expect(ShareVisibility.where(id: @persons_sv.map(&:id))).to be_empty - end - - it "deletes all of bobs aspect visiblites" do - expect(AspectVisibility.where(id: @aspect_vis.map(&:id))).to be_empty - end - - it "deletes all aspects" do - expect(bob.aspects).to be_empty - end - - it "deletes all user contacts" do - expect(bob.contacts).to be_empty - end - - it "clears the account fields" do - bob.send(:clearable_fields).each do |field| - expect(bob.reload[field]).to be_blank - end - end - - it_should_behave_like "it removes the person associations" +describe "deleteing account", type: :request do + def account_removal_method + AccountDeleter.new(subject.diaspora_handle).perform! + subject.reload end - context "remote person" do + context "of local user" do + subject(:user) { FactoryGirl.create(:user_with_aspect) } + before do - @person = remote_raphael - - # contacts - @contacts = @person.contacts - - # posts - @posts = (1..3).map do - FactoryGirl.create(:status_message, author: @person) - end - - @persons_sv = @posts.each do |post| - @contacts.each do |contact| - ShareVisibility.create!(user_id: contact.user.id, shareable: post) - end - end - - # photos - @photo = FactoryGirl.create(:photo, author: @person) - - # mentions - @mentions = 3.times do - FactoryGirl.create(:mention, person: @person) - end - - # conversations - create_conversation_with_message(alice, @person, "Subject", "Hey bob") - - AccountDeleter.new(@person.diaspora_handle).perform! - @person.reload + DataGenerator.create(subject, :generic_user_data) end - it_should_behave_like "it removes the person associations" + it "deletes all of the user data" do + expect { + account_removal_method + }.to change(nil, "user preferences empty?") { UserPreference.where(user_id: user.id).empty? }.to(be_truthy) + .and(change(nil, "notifications empty?") { Notification.where(recipient_id: user.id).empty? }.to(be_truthy)) + .and(change(nil, "blocks empty?") { Block.where(user_id: user.id).empty? }.to(be_truthy)) + .and(change(nil, "services empty?") { Service.where(user_id: user.id).empty? }.to(be_truthy)) + .and(change(nil, "share visibilities empty?") { ShareVisibility.where(user_id: user.id).empty? }.to(be_truthy)) + .and(change(nil, "aspects empty?") { user.aspects.empty? }.to(be_truthy)) + .and(change(nil, "contacts empty?") { user.contacts.empty? }.to(be_truthy)) + .and(change(nil, "tag followings empty?") { user.tag_followings.empty? }.to(be_truthy)) + .and(change(nil, "clearable fields blank?") { + user.send(:clearable_fields).map {|field| + user.reload[field].blank? + } + }.to(eq([true] * user.send(:clearable_fields).count))) + end + + it_behaves_like "it removes the person associations" do + subject(:person) { user.person } + end + end + + context "of remote person" do + subject(:person) { remote_raphael } + + before do + DataGenerator.create(subject, :generic_person_data) + end + + it_behaves_like "it removes the person associations" end end diff --git a/spec/misc_spec.rb b/spec/misc_spec.rb index 1e9851fa9..2661bc774 100644 --- a/spec/misc_spec.rb +++ b/spec/misc_spec.rb @@ -78,7 +78,7 @@ describe 'making sure the spec runner works' do describe "#create_conversation_with_message" do it 'creates a conversation and a message' do - conversation = create_conversation_with_message(alice, bob.person, "Subject", "Hey Bob") + conversation = create_conversation_with_message(alice.person, bob.person, "Subject", "Hey Bob") expect(conversation.participants).to eq([alice.person, bob.person]) expect(conversation.subject).to eq("Subject") diff --git a/spec/shared_behaviors/account_deletion.rb b/spec/shared_behaviors/account_deletion.rb index 48500e0d0..19f7bf4fc 100644 --- a/spec/shared_behaviors/account_deletion.rb +++ b/spec/shared_behaviors/account_deletion.rb @@ -2,32 +2,27 @@ # licensed under the Affero General Public License version 3 or later. See # the COPYRIGHT file. -shared_examples_for 'it removes the person associations' do - it "removes all of the person's posts" do - expect(Post.where(:author_id => @person.id).count).to eq(0) - end +shared_examples_for "it removes the person associations" do + RSpec::Matchers.define_negated_matcher :remain, :change - it 'deletes all person contacts' do - expect(Contact.where(:person_id => @person.id)).to be_empty - end - - it 'deletes all mentions' do - expect(@person.mentions).to be_empty - end - - it "removes all of the person's photos" do - expect(Photo.where(:author_id => @person.id)).to be_empty - end - - it 'sets the person object as closed and the profile is cleared' do - expect(@person.reload.closed_account).to be true - - expect(@person.profile.reload.first_name).to be_blank - expect(@person.profile.reload.last_name).to be_blank - end - - it 'deletes only the converersation visibility for the deleted user' do - expect(ConversationVisibility.where(:person_id => alice.person.id)).not_to be_empty - expect(ConversationVisibility.where(:person_id => @person.id)).to be_empty + it "removes all of the person associations" do + expect { + account_removal_method + }.to change(nil, "posts empty?") { Post.where(author_id: person.id).empty? }.to(be_truthy) + .and(change(nil, "contacts empty?") { Contact.where(person_id: person.id).empty? }.to(be_truthy)) + .and(change(nil, "mentions empty?") { person.mentions.empty? }.to(be_truthy)) + .and(change(nil, "photos empty?") { Photo.where(author_id: person.id).empty? }.to(be_truthy)) + .and(change(nil, "participations empty?") { Participation.where(author_id: person.id).empty? }.to(be_truthy)) + .and(change(nil, "roles empty?") { Role.where(person_id: person.id).empty? }.to(be_truthy)) + .and(change(person, :closed_account).to(be_truthy)) + .and(change(nil, "first name is blank?") { person.profile.first_name.blank? }.to(be_truthy)) + .and(change(nil, "last name is blank?") { person.profile.last_name.blank? }.to(be_truthy)) + .and(change(nil, "conversation visibilities empty?") { + ConversationVisibility.where(person_id: person.id).empty? + }.to(be_truthy)) + .and(remain(nil, "conversations empty?") { Conversation.where(author: person).empty? }.from(be_falsey)) + .and(remain(nil, "conversation visibilities of other participants empty?") { + ConversationVisibility.where(conversation: Conversation.where(author: person)).empty? + }.from(be_falsey)) end end diff --git a/spec/support/data_generator.rb b/spec/support/data_generator.rb new file mode 100644 index 000000000..bf93a8bfe --- /dev/null +++ b/spec/support/data_generator.rb @@ -0,0 +1,122 @@ +# TODO: docs +class DataGenerator + def person + @person || user.person + end + + def user + @user || person.owner + end + + def initialize(user_or_person) + if user_or_person.is_a? User + @user = user_or_person + elsif user_or_person.is_a? Person + @person = user_or_person + else + raise ArgumentError + end + end + + def self.create(user_or_person, type) + generator = new(user_or_person) + if type.is_a? Symbol + generator.send(type) + elsif type.is_a? Array + type.each {|type| + generator.send(type) + } + end + end + + def generic_user_data + preferences + notifications + blocks + service + private_post_as_receipient + tag_following + generic_person_data + end + + def generic_person_data + private_status_message + mention + photo + conversations + role + participation + end + + def preferences + %w[mentioned liked reshared].each do |pref| + user.user_preferences.create!(email_type: pref) + end + end + + def notifications + FactoryGirl.create(:notification, recipient: user) + end + + def conversations + a_friend = person.contacts.first.user.person + create_conversation_with_message(a_friend, person, "Subject", "Hey #{person.name}") + create_conversation_with_message(person, a_friend, "Subject", "Hey #{a_friend.name}") + end + + def blocks + user.blocks.create!(person: eve.person) + eve.blocks.create!(person: person) + end + + def service + FactoryGirl.create(:service, user: user) + end + + def private_post_as_receipient + friend = mutual_friend + friend.post( + :status_message, + text: text_mentioning(user), + to: friend.aspects.first + ) + end + + def tag_following + TagFollowing.create!(tag: random_tag, user: user) + end + + def random_tag + ActsAsTaggableOn::Tag.create!(name: "partytimeexcellent#{r_str}") + end + + def mutual_friend + FactoryGirl.create(:user_with_aspect).tap {|friend| + connect_users(user, first_aspect, friend, friend.aspects.first) + } + end + + def first_aspect + user.aspects.first || FactoryGirl.create(:aspect, user: user) + end + + def private_status_message + post = FactoryGirl.create(:status_message, author: person) + + person.contacts.each do |contact| + ShareVisibility.create!(user_id: contact.user.id, shareable: post) + end + end + + %i(photo participation).each do |factory| + define_method factory do + FactoryGirl.create(factory, author: person) + end + end + + %i[mention role].each do |factory| + define_method factory do + FactoryGirl.create(factory, person: person) + end + end +end