diff --git a/app/models/user.rb b/app/models/user.rb index 83ce569f666a169ded6c64126495192701ff5dc5..9713114715a86fca3369aa938219d53c3e3a11b6 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -100,37 +100,33 @@ class User def move_friend(opts = {}) return true if opts[:to] == opts[:from] - friend = Person.first(:_id => opts[:friend_id]) - if self.friend_ids.include?(friend.id) - from_aspect = self.aspect_by_id(opts[:from]) - to_aspect = self.aspect_by_id(opts[:to]) - if from_aspect && to_aspect - posts_to_move = from_aspect.posts.find_all_by_person_id(friend.id) - to_aspect.people << friend - to_aspect.posts << posts_to_move - from_aspect.person_ids.delete(friend.id.to_id) - posts_to_move.each { |x| from_aspect.post_ids.delete(x.id) } - from_aspect.save - to_aspect.save + if opts[:friend_id] && opts[:to] && opts[:from] + from_aspect = self.aspects.first(:_id => opts[:from]) + posts_to_move = from_aspect.posts.find_all_by_person_id(opts[:friend_id]) + if add_person_to_aspect(opts[:friend_id], opts[:to], :posts => posts_to_move) + delete_person_from_aspect(opts[:friend_id], opts[:from], :posts => posts_to_move) return true end end false end - def add_person_to_aspect(person_id, aspect_id) + def add_person_to_aspect(person_id, aspect_id, opts = {}) raise "Can not add person to an aspect you do not own" unless aspect = self.aspects.find_by_id(aspect_id) raise "Can not add person you are not friends with" unless person = self.find_friend_by_id(person_id) raise 'Can not add person who is already in the aspect' if aspect.person_ids.include?(person_id) aspect.people << person + opts[:posts] ||= self.raw_visible_posts.all(:person_id => person_id) + + aspect.posts += opts[:posts] aspect.save end - def delete_person_from_aspect(person_id, aspect_id) + def delete_person_from_aspect(person_id, aspect_id, opts = {}) raise "Can not delete a person from an aspect you do not own" unless aspect = self.aspects.find_by_id(aspect_id) aspect.person_ids.delete(person_id) - id_array = aspect.posts.all(:person_id => person_id, :select => "_id").collect{|x| x.id} - aspect.post_ids = aspect.post_ids - id_array + opts[:posts] ||= aspect.posts.all(:person_id => person_id) + aspect.posts -= opts[:posts] aspect.save end diff --git a/spec/models/aspect_spec.rb b/spec/models/aspect_spec.rb index abb995ebdf73a7162f4d14618d406945fcbbea13..1c10f9bf166a3ceeb6c126be476972d374a34bec 100644 --- a/spec/models/aspect_spec.rb +++ b/spec/models/aspect_spec.rb @@ -5,123 +5,128 @@ require 'spec_helper' describe Aspect do - before do - @user = Factory.create(:user) - @friend = Factory.create(:person) - @user2 = Factory.create(:user) - @friend_2 = Factory.create(:person) - end + let(:user ) { Factory.create(:user) } + let(:friend) { Factory.create(:person) } + let(:user2) { Factory.create(:user) } + let(:friend_2) { Factory.create(:person) } + + let(:aspect) {user.aspect(:name => 'losers')} + let(:aspect2) {user2.aspect(:name => 'failures')} + let(:aspect1) {user.aspect(:name => 'cats')} + let(:not_friend) { Factory(:person, :diaspora_handle => "not@person.com")} + let(:user3) {Factory(:user)} + let(:aspect3) {user3.aspect(:name => "lala")} describe 'creation' do it 'should have a name' do - aspect = @user.aspect(:name => 'losers') + aspect = user.aspect(:name => 'losers') aspect.name.should == "losers" end it 'should be creatable with people' do - aspect = @user.aspect(:name => 'losers', :people => [@friend, @friend_2]) + aspect = user.aspect(:name => 'losers', :people => [friend, friend_2]) aspect.people.size.should == 2 end it 'should be able to have other users' do - aspect = @user.aspect(:name => 'losers', :people => [@user2.person]) - aspect.people.include?(@user.person).should be false - aspect.people.include?(@user2.person).should be true + aspect = user.aspect(:name => 'losers', :people => [user2.person]) + aspect.people.include?(user.person).should be false + aspect.people.include?(user2.person).should be true aspect.people.size.should == 1 end it 'should be able to have users and people' do - aspect = @user.aspect(:name => 'losers', :people => [@user2.person, @friend_2]) - aspect.people.include?(@user.person).should be false - aspect.people.include?(@user2.person).should be true - aspect.people.include?(@friend_2).should be true + aspect = user.aspect(:name => 'losers', :people => [user2.person, friend_2]) + aspect.people.include?(user.person).should be false + aspect.people.include?(user2.person).should be true + aspect.people.include?(friend_2).should be true aspect.people.size.should == 2 end end describe 'validation' do before do - @aspect = @user.aspect(:name => 'losers') + @aspect = user.aspect(:name => 'losers') end it 'has a unique name for one user' do - aspect2 = @user.aspect(:name => @aspect.name) + aspect2 = user.aspect(:name => @aspect.name) aspect2.valid?.should be_false end it 'has no uniqueness between users' do - aspect2 = @user2.aspect(:name => @aspect.name) + aspect2 = user2.aspect(:name => @aspect.name) aspect2.valid?.should be_true end end describe 'querying' do before do - @aspect = @user.aspect(:name => 'losers') - @user.activate_friend(@friend, @aspect) - @aspect2 = @user2.aspect(:name => 'failures') - friend_users(@user, @aspect, @user2, @aspect2) + @aspect = user.aspect(:name => 'losers') + user.activate_friend(friend, @aspect) + @aspect2 = user2.aspect(:name => 'failures') + friend_users(user, @aspect, user2, @aspect2) @aspect.reload end it 'belong to a user' do - @aspect.user.id.should == @user.id - @user.aspects.size.should == 3 + @aspect.user.id.should == user.id + user.aspects.size.should == 3 end it 'should have people' do - @aspect.people.all.include?(@friend).should be true + @aspect.people.all.include?(friend).should be true @aspect.people.size.should == 2 end it 'should be accessible through the user' do - aspects = @user.aspects_with_person(@friend) + aspects = user.aspects_with_person(friend) aspects.size.should == 1 aspects.first.id.should == @aspect.id aspects.first.people.size.should == 2 - aspects.first.people.include?(@friend).should be true - aspects.first.people.include?(@user2.person).should be true + aspects.first.people.include?(friend).should be true + aspects.first.people.include?(user2.person).should be true end end describe 'posting' do it 'should add post to aspect via post method' do - aspect = @user.aspect(:name => 'losers', :people => [@friend]) + aspect = user.aspect(:name => 'losers', :people => [friend]) - status_message = @user.post( :status_message, :message => "hey", :to => aspect.id ) + status_message = user.post( :status_message, :message => "hey", :to => aspect.id ) aspect.reload aspect.posts.include?(status_message).should be true end it 'should add post to aspect via receive method' do - aspect = @user.aspect(:name => 'losers') - aspect2 = @user2.aspect(:name => 'winners') - friend_users(@user, aspect, @user2, aspect2) + aspect = user.aspect(:name => 'losers') + aspect2 = user2.aspect(:name => 'winners') + friend_users(user, aspect, user2, aspect2) - message = @user2.post(:status_message, :message => "Hey Dude", :to => aspect2.id) + message = user2.post(:status_message, :message => "Hey Dude", :to => aspect2.id) - @user.receive message.to_diaspora_xml, @user2.person + user.receive message.to_diaspora_xml, user2.person aspect.reload aspect.posts.include?(message).should be true - @user.visible_posts(:by_members_of => aspect).include?(message).should be true + user.visible_posts(:by_members_of => aspect).include?(message).should be true end it 'should retract the post from the aspects as well' do - aspect = @user.aspect(:name => 'losers') - aspect2 = @user2.aspect(:name => 'winners') - friend_users(@user, aspect, @user2, aspect2) + aspect = user.aspect(:name => 'losers') + aspect2 = user2.aspect(:name => 'winners') + friend_users(user, aspect, user2, aspect2) - message = @user2.post(:status_message, :message => "Hey Dude", :to => aspect2.id) + message = user2.post(:status_message, :message => "Hey Dude", :to => aspect2.id) - @user.receive message.to_diaspora_xml, @user2.person + user.receive message.to_diaspora_xml, user2.person aspect.reload aspect.post_ids.include?(message.id).should be true - retraction = @user2.retract(message) - @user.receive retraction.to_diaspora_xml, @user2.person + retraction = user2.retract(message) + user.receive retraction.to_diaspora_xml, user2.person aspect.reload @@ -129,129 +134,128 @@ describe Aspect do end end - context "aspect editing" do - let(:aspect) {@user.aspect(:name => 'losers')} - let(:aspect2) {@user2.aspect(:name => 'failures')} - let(:aspect1) {@user.aspect(:name => 'cats')} - let(:not_friend) { Factory(:person, :diaspora_handle => "not@person.com")} - let(:user3) {Factory(:user)} - let(:aspect3) {user3.aspect(:name => "lala")} - - before do - friend_users(@user, aspect, @user2, aspect2) - aspect.reload - @user.reload - end - - it 'should be able to move a friend from one of users existing aspects to another' do - @user.move_friend(:friend_id => @user2.person.id, :from => aspect.id, :to => aspect1.id) - aspect.reload - aspect1.reload + context "aspect management" do - aspect.person_ids.include?(@user2.person.id).should be false - aspect1.people.include?(@user2.person).should be true - end - it "should not move a person who is not a friend" do - @user.move_friend(:friend_id => @friend.id, :from => aspect.id, :to => aspect1.id) - aspect.reload - aspect1.reload - aspect.people.include?(@friend).should be false - aspect1.people.include?(@friend).should be false - end - - it "should not move a person to a aspect that's not his" do - @user.move_friend(:friend_id => @user2.person.id, :from => aspect.id, :to => aspect2.id) + before do + friend_users(user, aspect, user2, aspect2) aspect.reload - aspect2.reload - aspect.people.include?(@user2.person).should be true - aspect2.people.include?(@user2.person).should be false - end - - it 'should move all posts by that user to the new aspect' do - message = @user2.post(:status_message, :message => "Hey Dude", :to => aspect2.id) - - @user.receive message.to_diaspora_xml, @user2.person - aspect.reload - - aspect.posts.count.should == 1 - aspect1.posts.count.should == 0 - - @user.reload - @user.move_friend(:friend_id => @user2.person.id, :from => aspect.id, :to => aspect1.id) - aspect.reload - aspect1.reload - - aspect1.posts.count.should == 1 - aspect.posts.count.should == 0 + user.reload end + describe "#add_person_to_aspect" do it 'adds the user to the aspect' do - aspect1.people.should_not include @user2.person - @user.add_person_to_aspect(@user2.person.id, aspect1.id) + aspect1.people.should_not include user2.person + user.add_person_to_aspect(user2.person.id, aspect1.id) aspect1.reload - aspect1.people.should include @user2.person + aspect1.people.should include user2.person end it 'raises if its an aspect that the user does not own'do - proc{@user.add_person_to_aspect(@user2.person.id, aspect2.id) }.should raise_error /Can not add person to an aspect you do not own/ + proc{user.add_person_to_aspect(user2.person.id, aspect2.id) }.should raise_error /Can not add person to an aspect you do not own/ end it 'does not allow to have duplicate people in an aspect' do - proc{@user.add_person_to_aspect(not_friend.id, aspect1.id) }.should raise_error /Can not add person you are not friends with/ + proc{user.add_person_to_aspect(not_friend.id, aspect1.id) }.should raise_error /Can not add person you are not friends with/ end it 'does not allow you to add a person if they are already in the aspect' do - proc{@user.add_person_to_aspect(@user2.person.id, aspect.id) }.should raise_error /Can not add person who is already in the aspect/ + proc{user.add_person_to_aspect(user2.person.id, aspect.id) }.should raise_error /Can not add person who is already in the aspect/ end end describe '#delete_person_from_aspect' do it 'deletes a user from the aspect' do - @user.add_person_to_aspect(@user2.person.id, aspect1.id) - @user.reload - @user.aspects.find_by_id(aspect1.id).people.include?(@user2.person).should be true - @user.delete_person_from_aspect(@user2.person.id, aspect1.id) - @user.reload - @user.aspects.find_by_id(aspect1.id).people.include?(@user2.person).should be false + user.add_person_to_aspect(user2.person.id, aspect1.id) + user.reload + user.aspects.find_by_id(aspect1.id).people.include?(user2.person).should be true + user.delete_person_from_aspect(user2.person.id, aspect1.id) + user.reload + user.aspects.find_by_id(aspect1.id).people.include?(user2.person).should be false end it 'should check to make sure you have the aspect ' do - proc{@user.delete_person_from_aspect(@user2.person.id, aspect2.id) }.should raise_error /Can not delete a person from an aspect you do not own/ + proc{user.delete_person_from_aspect(user2.person.id, aspect2.id) }.should raise_error /Can not delete a person from an aspect you do not own/ + end + end + + context 'moving and removing posts' do + + let(:message) { user2.post(:status_message, :message => "Hey Dude", :to => aspect2.id)} + let(:message2){user3.post(:status_message, :message => "other post", :to => aspect3.id)} + + before do + friend_users(user, aspect, user3, aspect3) + user.receive message.to_diaspora_xml, user2.person + user.receive message2.to_diaspora_xml, user3.person + aspect.reload + @post_count = aspect.posts.count + @post_count1 = aspect1.posts.count + + user.reload + end + + it 'moves the persons posts into the new aspect' do + user.add_person_to_aspect(user2.person.id, aspect1.id, :posts => [message] ) + aspect1.reload + aspect1.posts.should == [message] end - context 'removing posts' do - before do - friend_users(@user, aspect, user3, aspect3) + + it 'should remove the users posts from that aspect' do + user.delete_person_from_aspect(user2.person.id, aspect.id) + aspect.reload + aspect.posts.count.should == @post_count - 1 + end - message = @user2.post(:status_message, :message => "Hey Dude", :to => aspect2.id) - @user.receive message.to_diaspora_xml, @user2.person - aspect.reload - aspect.posts.count.should == 1 - end + it 'should not delete other peoples posts' do + user.delete_person_from_aspect(user2.person.id, aspect.id) + aspect.reload + aspect.posts.should == [message2] + end - it 'should remove the users posts from that aspect' do - @user.reload - @user.delete_person_from_aspect(@user2.person.id, aspect.id) - aspect.reload - aspect.posts.count.should == 0 - end + describe '#move_friend' do + it 'should be able to move a friend from one of users existing aspects to another' do + user.move_friend(:friend_id => user2.person.id, :from => aspect.id, :to => aspect1.id) + aspect.reload + aspect1.reload - it 'should not delete other peoples posts' do - message2 = user3.post(:status_message, :message => "other post", :to => aspect3.id) + aspect.person_ids.include?(user2.person.id).should be false + aspect1.people.include?(user2.person).should be true + end - @user.receive message2.to_diaspora_xml, user3.person + it "should not move a person who is not a friend" do + proc{ user.move_friend(:friend_id => friend.id, :from => aspect.id, :to => aspect1.id) }.should raise_error /Can not add person you are not friends with/ + aspect.reload + aspect1.reload + aspect.people.include?(friend).should be false + aspect1.people.include?(friend).should be false + end - aspect.reload - aspect.posts.count.should == 2 + it "should not move a person to a aspect that's not his" do + proc {user.move_friend(:friend_id => user2.person.id, :from => aspect.id, :to => aspect2.id )}.should raise_error /Can not add person to an aspect you do not own/ + aspect.reload + aspect2.reload + aspect.people.include?(user2.person).should be true + aspect2.people.include?(user2.person).should be false + end - @user.reload - @user.delete_person_from_aspect(@user2.person.id, aspect.id) - aspect.reload - aspect.posts.should == [message2] - end + it 'should move all posts by that user to the new aspect' do + user.move_friend(:friend_id => user2.person.id, :from => aspect.id, :to => aspect1.id) + aspect.reload + aspect1.reload + + aspect1.posts.count.should == @post_count1 + 1 + aspect.posts.count.should == @post_count - 1 + end + + it 'does not try to delete if add person did not go through' do + user.should_receive(:add_person_to_aspect).and_return(false) + user.should_not_receive(:delete_person_from_aspect) + user.move_friend(:friend_id => user2.person.id, :from => aspect.id, :to => aspect1.id) end end + end end end