diff --git a/app/controllers/users_controller.rb b/app/controllers/users_controller.rb index aacff8504..9b923395f 100644 --- a/app/controllers/users_controller.rb +++ b/app/controllers/users_controller.rb @@ -86,16 +86,13 @@ class UsersController < ApplicationController def import xml = params[:upload][:file].read - params[:user][:diaspora_handle] = 'asodij@asodij.asd' - - begin importer = Diaspora::Importer.new(Diaspora::Parsers::XML) importer.execute(xml, params[:user]) flash[:notice] = "hang on a sec, try logging in!" rescue Exception => e - flash[:error] = "Derp, something went wrong: #{e.message}" + flash[:error] = "Something went wrong: #{e.message}" end redirect_to new_user_registration_path diff --git a/app/models/contact.rb b/app/models/contact.rb index 1b5a4b050..b11b591cb 100644 --- a/app/models/contact.rb +++ b/app/models/contact.rb @@ -4,6 +4,8 @@ class Contact include MongoMapper::Document + attr_accessor :aspect_names #this is only used in the importer + belongs_to :user validates_presence_of :user diff --git a/lib/diaspora/exporter.rb b/lib/diaspora/exporter.rb index 5f40322fb..c435749e3 100644 --- a/lib/diaspora/exporter.rb +++ b/lib/diaspora/exporter.rb @@ -22,16 +22,19 @@ module Diaspora xml.parent << user.person.to_xml } + + + xml.aspects { user.aspects.each do |aspect| xml.aspect { xml.name aspect.name - xml.person_ids { - aspect.person_ids.each do |id| - xml.person_id id - end - } +# xml.person_ids { + #aspect.person_ids.each do |id| + #xml.person_id id + #end + #} xml.post_ids { aspect.posts.find_all_by_person_id(user_person_id).each do |post| @@ -42,16 +45,25 @@ module Diaspora end } - xml.people { + xml.contacts { user.friends.each do |friend| - xml.parent << friend.to_xml + xml.contact { + xml.user_id friend.user_id + xml.person_id friend.person_id + + xml.aspects { + friend.aspects.each do |aspect| + xml.aspect { + xml.name aspect.name + } + end + } + } end } xml.posts { user.raw_visible_posts.find_all_by_person_id(user_person_id).each do |post| - #post_doc = post.to_xml - #post.comments.each do |comment| # post_doc << comment.to_xml #end @@ -59,6 +71,14 @@ module Diaspora xml.parent << post.to_xml end } + + xml.people { + user.friends.each do |friend| + person = friend.person + xml.parent << person.to_xml + + end + } } end diff --git a/lib/diaspora/importer.rb b/lib/diaspora/importer.rb index e1e8ad97f..57dd11ae9 100644 --- a/lib/diaspora/importer.rb +++ b/lib/diaspora/importer.rb @@ -9,8 +9,9 @@ module Diaspora self.class.send(:include, strategy) end - def commit(user, person, aspects, people, posts, opts = {}) - filter = verify_and_clean(user, person, people, aspects, posts) + def commit(user, person, aspects, people, posts, contacts, opts = {}) + filter = verify_and_clean(user, person, people, aspects, posts, contacts) + #assume data is good # to go @@ -27,11 +28,9 @@ module Diaspora user.visible_post_ids = filter[:whitelist].keys - user.friend_ids = people.collect{ |x| x.id } - user.visible_person_ids = user.friend_ids + #user.friend_ids = + user.visible_person_ids = people.collect{ |x| x.id } - user.save! - user.person.save! posts.each do |post| post.save! if filter[:unknown].include? post.id @@ -43,27 +42,59 @@ module Diaspora user.aspects << aspect end - - people.each do |p| p.save! if filter[:people].include? p.id.to_s end + + contacts.each do |contact| + contact.user = user + + user.friends << contact + contact.save! + end + + + puts user.persisted? + + puts user.inspect + user.save(:validate => false) + + + end + + def assign_aspect_ids(contacts, aspects) + a_hash = {} + aspects.each{|x| a_hash[x.name]=x.id} + + contacts.each do |contact| + contact.aspect_names.each do |x| + contact.aspect_ids << a_hash[x] + end + contact.aspect_names = nil + end + + end ### verification (to be module) ################ - def verify_and_clean(user, person, people, aspects, posts) + def verify_and_clean(user, person, people, aspects, posts, contacts) verify_user(user) verify_person_for_user(user, person) filters = filter_posts(posts, person) - - clean_aspects(aspects, filters[:whitelist]) + filters[:all_person_ids] = people.collect{ |x| x.id.to_id } - + raise "incorrect number of contacts" unless verify_contacts(contacts, filters[:all_person_ids]) + assign_aspect_ids(contacts, aspects) filters[:people] = filter_people(people) filters end + + def verify_contacts(contacts, person_ids) + return false if contacts.count != person_ids.count + contacts.all?{|x| person_ids.include?(x.person_id)} + end def verify_user(user) User.find_by_id(user.id).nil? ? true : raise("User already exists!") @@ -126,11 +157,12 @@ module Diaspora user, person = parse_user_and_person(doc) aspects = parse_aspects(doc) + contacts = parse_contacts(doc) people = parse_people(doc) posts = parse_posts(doc) - + user - commit(user, person, aspects, people, posts, opts) + commit(user, person, aspects, people, posts, contacts, opts) end def parse_user_and_person(doc) @@ -152,7 +184,6 @@ module Diaspora aspect = Aspect.new aspect.name = a.xpath('/aspect/name').text aspect.post_ids = a.xpath('/aspect/post_ids/post_id').collect{ |x| x.text.to_id } - aspect.person_ids = a.xpath('/aspect/person_ids/person_id').collect{ |x| x.text.to_id } aspects << aspect end aspects @@ -165,6 +196,18 @@ module Diaspora end end + def parse_contacts(doc) + contacts = [] + contact_doc = doc.xpath('/export/contacts/contact') + + contact_doc.each do |x| + contact = Contact.new + contact.person_id = x.xpath("person_id").text.to_id + contact.aspect_names = x.xpath('aspects/aspect/name').collect{ |x| x.text} + contacts << contact + end + contacts + end def parse_posts(doc) post_doc = doc.xpath('/export/posts/status_message') diff --git a/spec/lib/diaspora/exporter_spec.rb b/spec/lib/diaspora/exporter_spec.rb index 88369dacf..e2db3b5eb 100644 --- a/spec/lib/diaspora/exporter_spec.rb +++ b/spec/lib/diaspora/exporter_spec.rb @@ -11,6 +11,7 @@ describe Diaspora::Exporter do let!(:user2) { Factory(:user) } let!(:user3) { Factory(:user) } + let!(:aspect) { user1.aspect(:name => "Old Work") } let(:aspect1) { user1.aspect(:name => "Work") } let(:aspect2) { user2.aspect(:name => "Family") } let(:aspect3) { user3.aspect(:name => "Pivots") } @@ -19,47 +20,84 @@ describe Diaspora::Exporter do let!(:status_message2) { user1.post(:status_message, :message => "Two", :public => true, :to => aspect1.id) } let!(:status_message3) { user2.post(:status_message, :message => "Three", :public => false, :to => aspect2.id) } - let(:exported) { Diaspora::Exporter.new(Diaspora::Exporters::XML).execute(user1) } + let(:exported) { Nokogiri::XML(Diaspora::Exporter.new(Diaspora::Exporters::XML).execute(user1)) } - it 'should include a users posts' do - exported.should include status_message1.message - exported.should include status_message2.message - exported.should_not include status_message3.message + context '' do + let(:user_xml) {exported.xpath('//user').to_s} + it 'should include a users private key' do + user_xml.to_s.should include user1.serialized_private_key + end end - it 'should include a users private key' do - exported.should include user1.serialized_private_key + context '' do + let(:aspects_xml) {exported.xpath('//aspects').to_s} + it 'should include the aspect name' do + + end + + it 'should include the post_ids' do + aspects_xml.should include status_message1.id.to_s + aspects_xml.should include status_message2.id.to_s + end end - it 'should include post_ids' do - doc = Nokogiri::XML::parse(exported) - doc.xpath('//aspects').to_s.should include status_message1.id.to_s + context '' do - doc.xpath('//aspects').to_s.should include status_message2.id.to_s - doc.xpath('//posts').to_s.should include status_message1.id.to_s + before do + friend_users(user1, aspect1, user3, aspect3) + user1.add_person_to_aspect(user3.person.id, aspect.id) + user1.reload + end + + let(:contacts_xml) {exported.xpath('//contacts').to_s} + it 'should include a person id' do + contacts_xml.should include user3.person.id.to_s + end + + it 'should include an aspects names of all aspects they are in' do + #contact specific xml needs to be tested + user1.friends.find_by_person_id(user3.person.id).aspects.count.should > 0 + user1.friends.find_by_person_id(user3.person.id).aspects.each { |aspect| + contacts_xml.should include aspect.name + } + end end - it 'should include post created at time' do - doc = Nokogiri::XML::parse(exported) - Time.parse(doc.xpath('//posts/status_message/created_at').first.text).should == status_message1.created_at + context '' do + let(:people_xml) {exported.xpath('//people').to_s} + before do + friend_users(user1, aspect1, user3, aspect3) + user1.reload + end + it 'should include persons id' do + people_xml.should include user3.person.id.to_s + end + + it 'should include their profile' do + people_xml.should include user3.person.profile.first_name + people_xml.should include user3.person.profile.last_name + end + + it 'should include their public key' do + people_xml.should include user3.person.exported_key + end + + it 'should include their diaspora handle' do + people_xml.should include user3.person.diaspora_handle + end end - it 'should include a list of users posts' do - doc = Nokogiri::XML::parse(exported) - posts = doc.xpath('//posts').to_s - posts.should include(status_message1.message) - end - - it 'should serialize a users friends' do - friend_users(user1, aspect1, user3, aspect3) - doc = Nokogiri::XML::parse(exported) - doc.xpath('/export/people').to_s.should include user3.person.id.to_s - end - - it 'should serialize only a users posts within his aspects' do - message = Factory(:status_message, :message => "Shouldn't be here", :person => user3.person) - aspect1.posts << message - doc = Nokogiri::XML::parse(exported) - doc.xpath('/export/aspects').to_s.should_not include message.message + context '' do + let(:posts_xml) {exported.xpath('//posts').to_s} + it 'should include many posts xml' do + posts_xml.should include status_message1.message + posts_xml.should include status_message2.message + posts_xml.should_not include status_message3.message + end + + it 'should include post created at time' do + doc = Nokogiri::XML::parse(posts_xml) + Time.parse(doc.xpath('//posts/status_message/created_at').first.text).should == status_message1.created_at + end end end diff --git a/spec/lib/diaspora/importer_spec.rb b/spec/lib/diaspora/importer_spec.rb index 268b0f5e1..9d3197698 100644 --- a/spec/lib/diaspora/importer_spec.rb +++ b/spec/lib/diaspora/importer_spec.rb @@ -73,14 +73,14 @@ describe Diaspora::Importer do @user1.friends.count.should be 4 - @user1.friends.should include @user2.person - @user1.friends.should include @user3.person - @user1.friends.should include @user4.person - @user1.friends.should include @user5.person + @user1.contact_for(@user2.person).should_not be_nil + @user1.contact_for(@user3.person).should_not be_nil + @user1.contact_for(@user4.person).should_not be_nil + @user1.contact_for(@user5.person).should_not be_nil # User is generated with two pre-populated aspects @user1.aspects.count.should be 6 - @user1.aspects.find_by_name("Dudes").people.should include @user2.person + @user1.aspects.find_by_name("Dudes").people.find_by_person_id(@user2.person.id).should_not be_nil @user1.aspects.find_by_name("Dudes").posts.should include @status_message5 @user1.raw_visible_posts.count.should be 6 @@ -137,9 +137,21 @@ describe Diaspora::Importer do it 'should should have post ids' do aspects.any?{|x| x.post_ids.count > 0}.should be true end + end - it 'should have person ids' do - aspects.any?{|x| x.person_ids.count > 0}.should be true + describe '#parse_contacts' do + let(:contacts) { @importer.parse_contacts(@doc) } + + it 'should return an array' do + contacts.count.should == 4 + end + + it 'should should have post ids' do + contacts.all?{|x| x.aspect_names.count > 0}.should be true + end + + it 'should should have a person id' do + contacts.all?{|x| x.person_id.nil? || x.person_id == ""}.should be false end end @@ -172,9 +184,10 @@ describe Diaspora::Importer do # Generate exported XML for user1 exporter = Diaspora::Exporter.new(Diaspora::Exporters::XML) @xml = exporter.execute(@user1) - + @username =@user1.username # Remove user1 from the server @user1.aspects.each( &:delete ) + @user1.friends.each( &:delete ) @user1.raw_visible_posts.find_all_by_person_id(@user1.person.id).each( &:delete ) @user1.delete @@ -182,12 +195,15 @@ describe Diaspora::Importer do end it 'should import' do - pending "there is some weirdness with diaspora handle we need to look into... and this test is terrible" + pending "there is some weirdness with diaspora handle we need to look into... and this test needs love + the test passes when the validations are set to false when saving the user in the importer" + User.delete_all Person.delete_all Post.delete_all StatusMessage.delete_all Aspect.delete_all + Contact.delete_all User.count.should == 0 Person.count.should == 0 @@ -196,15 +212,18 @@ describe Diaspora::Importer do :email => "bob@bob.com", :password => "bobbybob", :password => "bobbybob", - :diaspora_handle => "bob@diaspora.com") + :diaspora_handle => "#{@username}@#{APP_CONFIG[:terse_pod_url]}") User.count.should == 1 n = User.first Post.count.should == 4 n.aspects.count.should == 6 Person.count.should be == 5 + Contact.count.should be == 4 - User.first.person.diaspora_handle.should == User.first.diaspora_handle + # need to check this + #User.first.person.diaspora_handle.should == User.first.diaspora_handle + User.first.diaspora_handle.should == "#{@username}@#{APP_CONFIG[:terse_pod_url]}" Person.find_by_id( @user1.person.id ).nil?.should == false @@ -223,12 +242,7 @@ describe Diaspora::Importer do n.friends.count.should be 4 end - - - end - end - end diff --git a/spec/lib/verify_spec.rb b/spec/lib/verify_spec.rb index b0b8a0de6..03df9d026 100644 --- a/spec/lib/verify_spec.rb +++ b/spec/lib/verify_spec.rb @@ -51,6 +51,23 @@ describe Diaspora::Importer do end end + describe 'verify contacts' do + let(:contact1) {Contact.new(:user => user1, :person => user2.person, :aspects => [aspect1])} + let(:contact2) {Contact.new(:user => user1, :person => user3.person, :aspects => [aspect2])} + let(:contact3) {Contact.new(:user => user1, :person => user3.person, :aspects => [aspect3])} + let(:less_contacts) {[contact1]} + let(:same_contacts) {[contact1, contact2]} + let(:more_contacts) {[contact1, contact2, contact3]} + + let(:person_ids) {[user2.person.id, user3.person.id]} + + + it 'should be false if the number of the number of contacts is not equal to the number of imported people' do + importer.verify_contacts(less_contacts, person_ids).should be false + importer.verify_contacts(same_contacts, person_ids).should be true + importer.verify_contacts(more_contacts, person_ids).should be false + end + end describe '#filter_posts' do it 'should make sure all found posts are owned by the user' do