diff --git a/app/controllers/sessions_controller.rb b/app/controllers/sessions_controller.rb new file mode 100644 index 0000000000000000000000000000000000000000..cda4aac848a1fcd5d17b2fe155885d289f784e7c --- /dev/null +++ b/app/controllers/sessions_controller.rb @@ -0,0 +1,17 @@ +# Copyright (c) 2010, Diaspora Inc. This file is +# licensed under the Affero General Public License version 3 or later. See +# the COPYRIGHT file. + +class SessionsController < Devise::SessionsController + + after_filter :enqueue_update, :only => :create + protected + def enqueue_update + if current_user + pp params + current_user.services.each{|s| + Resque.enqueue(Job::UpdateServiceUsers, s.id) if s.respond_to? :save_friends + } + end + end +end diff --git a/app/models/jobs/update_service_users.rb b/app/models/jobs/update_service_users.rb index 690306967deec85f327015fd78a07cf4c145809a..f2ffed4987c1a6696a53f333757ef1bf78529720 100644 --- a/app/models/jobs/update_service_users.rb +++ b/app/models/jobs/update_service_users.rb @@ -5,6 +5,7 @@ module Job class UpdateServiceUsers < Base + @queue = :http_service def self.perform_delegate(service_id) service = Service.find(service_id) service.save_friends diff --git a/app/models/service.rb b/app/models/service.rb index 1225e547b1614429cb6391f774096836c726d19a..1c8737380d8d6494844147c2ff36a2ff6015bad5 100644 --- a/app/models/service.rb +++ b/app/models/service.rb @@ -6,6 +6,7 @@ class Service < ActiveRecord::Base include ActionView::Helpers::TextHelper belongs_to :user + has_many :service_users def public_message(post, length, url = "") url = "" if post.respond_to?(:photos) && post.photos.count == 0 diff --git a/app/models/services/facebook.rb b/app/models/services/facebook.rb index a24601a5a5ee2e1defe2048015d7dac112a90e72..fb9d0d75790b506791035be84a14471695360a3c 100644 --- a/app/models/services/facebook.rb +++ b/app/models/services/facebook.rb @@ -21,46 +21,16 @@ class Services::Facebook < Service def finder(opts = {}) Rails.logger.debug("event=friend_finder type=facebook sender_id=#{self.user_id}") - response = RestClient.get("https://graph.facebook.com/me/friends", {:params => {:access_token => self.access_token}}) - data = JSON.parse(response.body)['data'] - - data_h = {} - data.each do |d| - data_h[d['id']] = {:name => d['name']} - end - - invitation_objects = Invitation.joins(:recipient).where(:sender_id => self.user_id, - :users => {:invitation_service => 'facebook', - :invitation_identifier => data_h.keys}) - - invitation_objects.each do |inv| - data_h[inv.recipient.invitation_identifier][:invitation_id] = inv.id - end - - service_objects = Services::Facebook.where(:uid => data_h.keys).includes(:user => {:person => :profile}) - person_ids_and_uids = {} - - service_objects.each do |s| - data_h[s.uid][:person] = s.user.person if s.user.person.profile.searchable - person_ids_and_uids[s.user.person.id] = s.uid - end - - requests = Request.where(:recipient_id => self.user.person.id, :sender_id => person_ids_and_uids.keys).all - requests.each{|r| data_h[person_ids_and_uids[r.sender_id]][:request] = r} - - - contact_objects = Contact.unscoped.where(:user_id => self.user.id, :person_id => person_ids_and_uids.keys) - contact_objects.each{|c| data_h[person_ids_and_uids[c.person_id]][:contact] = c} - + Resque.enqueue(Job::UpdateServiceUsers, self.id) + person = Person.arel_table + service_user = ServiceUser.arel_table if opts[:local] - data_h.delete_if {|key, value| value[:person].nil? } - end - - if opts[:remote] - data_h.delete_if {|key, value| !value[:person].nil? } + ServiceUser.joins(:person).where(:service_id => self.id).where(person[:owner_id].not_eq(nil)) + elsif opts[:remote] + ServiceUser.joins(:person).where(:service_id => self.id).where(person[:owner_id].eq(nil)) + else + self.service_users end - - data_h end def save_friends @@ -68,7 +38,7 @@ class Services::Facebook < Service {:fields => ['name', 'id', 'picture'], :access_token => self.access_token}}) data = JSON.parse(response.body)['data'] data.each{ |p| - ServiceUser.find_or_create(:service_id => self.id, :name => p["name"], + ServiceUser.find_or_create_by_service_id_and_name_and_uid_and_photo_url(:service_id => self.id, :name => p["name"], :uid => p["id"], :photo_url => p["picture"]) } end diff --git a/app/views/devise/sessions/new.haml b/app/views/sessions/new.haml similarity index 93% rename from app/views/devise/sessions/new.haml rename to app/views/sessions/new.haml index 1e9b883a36e57c3ce9ab172f5c341c9ab0039d3d..a738248c6f03e74c2f197b07f6051bbeabf051d1 100644 --- a/app/views/devise/sessions/new.haml +++ b/app/views/sessions/new.haml @@ -54,11 +54,11 @@ \. %p.submit - = f.submit t('.sign_in') + = f.submit t('devise.sessions.new.sign_in') %span#remember_me - if devise_mapping.rememberable? = f.check_box :remember_me - = f.label :remember_me, t('.remember_me') + = f.label :remember_me, t('devise.sessions.new.remember_me') - else \. diff --git a/app/views/devise/sessions/new.mobile.haml b/app/views/sessions/new.mobile.haml similarity index 84% rename from app/views/devise/sessions/new.mobile.haml rename to app/views/sessions/new.mobile.haml index 1f272971764d7f746af034eaa62858a65d2044fb..d41ebe3103c4f50288db622838eeef7b35517dce 100644 --- a/app/views/devise/sessions/new.mobile.haml +++ b/app/views/sessions/new.mobile.haml @@ -13,10 +13,10 @@ %p = f.label :password , t('password') = f.password_field :password - = f.submit t('.sign_in') + = f.submit t('devise.sessions.new.sign_in') - if devise_mapping.rememberable? = f.check_box :remember_me - = f.label :remember_me, t('.remember_me') + = f.label :remember_me, t('devise.sessions.new.remember_me') %p = render :partial => "devise/shared/links" diff --git a/config/routes.rb b/config/routes.rb index 2cf65a096084873d350eda1cd46643da36376247..7a7a1a2c9e7a538839584478f0086c66fa05b7ce 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -47,6 +47,7 @@ Diaspora::Application.routes.draw do devise_for :users, :controllers => {:registrations => "registrations", :password => "devise/passwords", + :sessions => "sessions", :invitations => "invitations"} do get 'invitations/resend/:id' => 'invitations#resend', :as => 'invitation_resend' diff --git a/spec/controllers/sessions_controller_spec.rb b/spec/controllers/sessions_controller_spec.rb new file mode 100644 index 0000000000000000000000000000000000000000..b3548feba6ae0b7db53f9ee42fca6677f28ea2e2 --- /dev/null +++ b/spec/controllers/sessions_controller_spec.rb @@ -0,0 +1,43 @@ +# Copyright (c) 2010, Diaspora Inc. This file is +# licensed under the Affero General Public License version 3 or later. See +# the COPYRIGHT file. + +require 'spec_helper' + +class Object + def id + super + end +end + +describe SessionsController do + include Devise::TestHelpers + + render_views + + let(:mock_access_token) { Object.new } + + let(:omniauth_auth) { + { 'provider' => 'twitter', + 'uid' => '2', + 'user_info' => { 'nickname' => 'grimmin' }, + 'credentials' => { 'token' => 'tokin', 'secret' =>"not_so_much" } + } + } + + before do + request.env["devise.mapping"] = Devise.mappings[:user] + @user = alice + @service = Services::Facebook.new(:access_token => "yeah") + @user.services << @service + @user.save + end + + describe "#create" do + it 'queues up an update job' do + Resque.should_receive(:enqueue).with(Job::UpdateServiceUsers, @service.id) + post :create, {"user"=>{"remember_me"=>"0", "username"=>"alice", + "password"=>"evankorth"}} + end + end +end diff --git a/spec/models/services/facebook_spec.rb b/spec/models/services/facebook_spec.rb index 4ce8beb4b22de91a9d43f2488bb15d3f802afa4f..fc69a03d0d101a61895de905bcd279fbf8c6cb20 100644 --- a/spec/models/services/facebook_spec.rb +++ b/spec/models/services/facebook_spec.rb @@ -27,11 +27,12 @@ describe Services::Facebook do end end - describe '#cache_friends' do + context 'finder' do before do @user2 = Factory.create(:user_with_aspect) @user2_fb_id = '820651' @user2_fb_name = 'Maxwell Salzberg' + @user2_fb_photo_url = "http://cdn.fn.com/pic1.jpg" @user2_service = Services::Facebook.new(:uid => @user2_fb_id, :access_token => "yo") @user2.services << @user2_service @fb_list_hash = <<JSON @@ -40,7 +41,7 @@ describe Services::Facebook do { "name": "#{@user2_fb_name}", "id": "#{@user2_fb_id}", - "picture": "http://cdn.fn.com/pic1.jpg" + "picture": "#{@user2_fb_photo_url}" }, { "name": "Person to Invite", @@ -55,29 +56,44 @@ JSON RestClient.stub!(:get).and_return(@web_mock) end - it 'requests a friend list' do - RestClient.should_receive(:get).with("https://graph.facebook.com/me/friends", {:params => - {:fields => ['name', 'id', 'picture'], :access_token => @service.access_token}}).and_return(@web_mock) - @service.save_friends - end + describe '#save_friends' do + it 'requests a friend list' do + RestClient.should_receive(:get).with("https://graph.facebook.com/me/friends", {:params => + {:fields => ['name', 'id', 'picture'], :access_token => @service.access_token}}).and_return(@web_mock) + @service.save_friends + end - it 'creates a service user objects' do - lambda{ - @service.save_friends - }.should change(ServiceUser, :count).by(2) + it 'creates a service user objects' do + lambda{ + @service.save_friends + }.should change(ServiceUser, :count).by(2) + end end - context 'only local' do - it 'does not return people who are remote' do - @service.finder(:local => true).should be_empty - @service.finder(:local => true).should_not be_empty + describe '#finder' do + it 'dispatches a resque job' do + Resque.should_receive(:enqueue).with(Job::UpdateServiceUsers, @service.id) + @service.finder end - end + context 'opts' do + it 'only local does not return people who are remote' do + @service.save_friends + @service.finder(:local => true).all.each{|su| su.person.should == @user2.person} + end + + it 'does not return people who are remote' do + @service.save_friends + @service.finder(:remote => true).all.each{|su| su.person.should be_nil} + end + + it 'does not return wrong service objects' do + su2 = ServiceUser.create(:service => @user2_service, :uid => @user2_fb_id, :name => @user2_fb_name, :photo_url => @user2_fb_photo_url) + su2.person.should == @user2.person - context 'only remote' do - it 'does not return people who are remote' do - @service.finder(:remote => true).should_not be_empty - @service.finder(:remote => true).should be_empty + @service.finder(:local => true).all.each{|su| su.service.should == @service} + @service.finder(:remote => true).all.each{|su| su.service.should == @service} + @service.finder.all.each{|su| su.service.should == @service} + end end end end