made websockets far less dumb. don't render partials for people not connected.

This commit is contained in:
danielgrippi 2011-03-15 18:20:16 -07:00
parent 1164303251
commit 68479481cf
7 changed files with 59 additions and 26 deletions

View file

@ -12,6 +12,7 @@ class SocketsController < ApplicationController
end
def outgoing(user, object, opts={})
return unless Diaspora::WebSocket.is_connected?(user.id)
@_request = ActionDispatch::Request.new({})
Diaspora::WebSocket.queue_to_user(user.id, action_hash(user, object, opts))
end

View file

@ -41,6 +41,7 @@ Cucumber::Rails::World.use_transactional_fixtures = false
require File.join(File.dirname(__FILE__), "database_cleaner_patches")
require File.join(File.dirname(__FILE__), "..", "..", "spec", "support", "fake_redis")
require File.join(File.dirname(__FILE__), "..", "..", "spec", "helper_methods")
include HelperMethods
@ -57,26 +58,6 @@ module Resque
end
end
module Diaspora::WebSocket
def self.redis
FakeRedis.new
end
end
class FakeRedis
def rpop(*args)
true
end
def llen(*args)
true
end
def lpush(*args)
true
end
end
Before('@localserver') do
TestServerFixture.start_if_needed
CapybaraSettings.instance.save

View file

@ -4,6 +4,9 @@
module Diaspora
module WebSocket
REDIS_CONNECTION_SET = 'ws-uids'
def self.redis
@redis ||= Resque.redis
end
@ -32,6 +35,8 @@ module Diaspora
self.ensure_channel(uid)
@channels[uid][0].subscribe{ |msg| ws.send msg }
@channels[uid][1] += 1
redis.sadd(REDIS_CONNECTION_SET, uid)
end
def self.ensure_channel(uid)
@ -44,8 +49,13 @@ module Diaspora
@channels[uid][1] -= 1
if @channels[uid][1] <= 0
@channels.delete(uid)
redis.srem(REDIS_CONNECTION_SET, uid)
end
end
def self.is_connected?(uid)
redis.sismember(REDIS_CONNECTION_SET, uid)
end
end
module Socketable

View file

@ -15,15 +15,11 @@ describe SocketsController do
before do
@user = alice
@controller = SocketsController.new
@aspect = @user.aspects.first
@message = @user.post :status_message, :text => "post through user for victory", :to => @aspect.id
end
describe 'actionhash' do
before do
@aspect = @user.aspects.first
@message = @user.post :status_message, :text => "post through user for victory", :to => @aspect.id
@fixture_name = File.dirname(__FILE__) + '/../fixtures/button.png'
end
it 'actionhashes posts' do
json = @controller.action_hash(@user, @message)
json.include?(@message.text).should be_true
@ -37,4 +33,17 @@ describe SocketsController do
json.include?("html\":null").should be_true
end
end
describe '#outgoing' do
it 'calls queue_to_user' do
Diaspora::WebSocket.should_receive(:is_connected?).with(@user.id).and_return(true)
Diaspora::WebSocket.should_receive(:queue_to_user).with(@user.id, anything)
@controller.outgoing(@user, @message)
end
it 'does not call queue_to_user if the user is not connected' do
Diaspora::WebSocket.should_receive(:is_connected?).with(@user.id).and_return(false)
Diaspora::WebSocket.should_not_receive(:queue_to_user)
@controller.outgoing(@user, @message)
end
end
end

View file

@ -28,6 +28,7 @@ describe 'a user receives a post' do
contact = @user1.contact_for(@user2.person)
@user1.add_contact_to_aspect(contact, @user1.aspects.create(:name => "villains"))
status = @user2.build_post(:status_message, :text => "Users do things", :to => @aspect2.id)
Diaspora::WebSocket.stub!(:is_connected?).and_return(true)
Diaspora::WebSocket.should_receive(:queue_to_user).exactly(:once)
zord = Postzord::Receiver.new(@user1, :object => status, :person => @user2.person)
zord.receive_object

View file

@ -21,6 +21,33 @@ describe Diaspora::WebSocket do
Diaspora::WebSocket.queue_to_user("me", "Socket!")
end
end
describe '.subscribe' do
it 'adds the uid to the uid redis set' do
Diaspora::WebSocket.stub!(:length)
Diaspora::WebSocket.initialize_channels
@mock_redis.should_receive(:sadd).with(Diaspora::WebSocket::REDIS_CONNECTION_SET, alice.id)
Diaspora::WebSocket.subscribe(alice.id, mock())
end
end
describe '.unsubscribe' do
it 'removes the uid to the uid redis set' do
Diaspora::WebSocket.stub!(:length)
Diaspora::WebSocket.initialize_channels
@mock_redis.stub!(:sadd)
Diaspora::WebSocket.subscribe(alice.id, mock())
@mock_redis.should_receive(:srem).with(Diaspora::WebSocket::REDIS_CONNECTION_SET, alice.id)
Diaspora::WebSocket.unsubscribe(alice.id, mock())
end
end
describe '.is_connected?' do
it 'calls sismember' do
@mock_redis.should_receive(:sismember).with(Diaspora::WebSocket::REDIS_CONNECTION_SET, alice.id)
Diaspora::WebSocket.is_connected?(alice.id)
end
end
end
describe Diaspora::Socketable do
@ -32,6 +59,7 @@ describe Diaspora::Socketable do
end
it 'sockets to a user' do
Diaspora::WebSocket.should_receive(:is_connected?).with(@user.id).and_return(true)
Diaspora::WebSocket.should_receive(:queue_to_user)
@post.socket_to_user(@user, :aspect_ids => @aspect.id)
end

View file

@ -14,4 +14,7 @@ class FakeRedis
def lpush(*args)
true
end
def sismember(*args)
false
end
end