Skip to content

Commit

Permalink
Make Handler configurable, add tests
Browse files Browse the repository at this point in the history
  • Loading branch information
skade committed Apr 12, 2012
1 parent 31532e9 commit 774858f
Show file tree
Hide file tree
Showing 3 changed files with 69 additions and 2 deletions.
3 changes: 2 additions & 1 deletion lib/slanger/config.rb
Expand Up @@ -13,7 +13,8 @@ def [](key)
def options
@options ||= {
api_host: '0.0.0.0', api_port: '4567', websocket_host: '0.0.0.0',
websocket_port: '8080', debug: false, redis_address: 'redis://0.0.0.0:6379/0'
websocket_port: '8080', debug: false, redis_address: 'redis://0.0.0.0:6379/0',
socket_handler: Slanger::Handler
}
end

Expand Down
2 changes: 1 addition & 1 deletion lib/slanger/web_socket_server.rb
Expand Up @@ -9,7 +9,7 @@ def run
# Keep track of handler instance in instance of EM::Connection to ensure a unique handler instance is used per connection.
ws.class_eval { attr_accessor :connection_handler }
# Delegate connection management to handler instance.
ws.onopen { ws.connection_handler = Slanger::Handler.new ws }
ws.onopen { ws.connection_handler = Slanger::Config.socket_handler.new ws }
ws.onmessage { |msg| ws.connection_handler.onmessage msg }
ws.onclose { ws.connection_handler.onclose }
end
Expand Down
66 changes: 66 additions & 0 deletions spec/integration/replaced_handler_spec.rb
@@ -0,0 +1,66 @@
require 'bundler/setup'

require 'active_support/json'
require 'active_support/core_ext/hash'
require 'eventmachine'
require 'em-http-request'
require 'pusher'
require 'thin'
require './spec/spec_helper'

describe 'replacable handler' do
let(:errback) { Proc.new { fail 'cannot connect to slanger. your box might be too slow. try increasing sleep value in the before block' } }

before(:each) do
# Fork service. Our integration tests MUST block the main thread because we want to wait for i/o to finish.
@server_pid = EM.fork_reactor do
require File.expand_path(File.dirname(__FILE__) + '/../../slanger.rb')

class ReplacedHandler < Slanger::Handler
def authenticate
super
@socket.send(payload nil, 'pusher:info', { message: "Welcome!" })
end
end

Thin::Logging.silent = true

Slanger::Config.load host: '0.0.0.0',
api_port: '4567',
websocket_port: '8080',
app_key: '765ec374ae0a69f4ce44',
secret: 'your-pusher-secret',
socket_handler: ReplacedHandler

Slanger::Service.run
end
# Give Slanger a chance to start
sleep 0.6
end

after(:each) do
# Ensure Slanger is properly stopped. No orphaned processes allowed!
Process.kill 'SIGKILL', @server_pid
Process.wait @server_pid
end

before :all do
Pusher.tap do |p|
p.host = '0.0.0.0'
p.port = 4567
p.app_id = 'your-pusher-app-id'
p.secret = 'your-pusher-secret'
p.key = '765ec374ae0a69f4ce44'
end
end

it 'immediately disconnects' do
msgs = em_stream do |websocket, messages|
if messages.length == 2
EM.stop
end
end

msgs.last.should == {"channel"=>nil, "event"=>"pusher:info", "data"=>{"message"=>"Welcome!"}}
end
end

2 comments on commit 774858f

@markburns
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I spent a bit of time on trying to improve the tests for this project by reducing duplication.
This test is a lot of setup (and duplication) for a simple test. Might be nice to try and minimize that.
I'm not sure what the solution is. Is it possible to share before/after/let blocks in rspec?

I've also been working quite a bit on a refactor to try and make some of the slanger code less procedural and
use more classes - it's on the misnomered branch at https://github.com/stevegraham/slanger/tree/rename_payload_to_connection

That should hopefully make it easier to unit test some of this instead of integration testing everything.

Seems like this test would be more appropriate if it could check the minimum - e.g. check that ReplacedHandler gets instantiated

@skade
Copy link
Member Author

@skade skade commented on 774858f Apr 19, 2012

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi Mark,

when it comes to sharing of before/after: I am no sure whether shared_examples_for can do that, I'll test later.

I just split up this file because I had the impression that integration tests are the only thing Slanger does. And considering the fact that this one needed slightly different setup, I took the easy route and created another integration test - the point of this pull request is not the testing setup :).

About the minimum check: How to you check properly whether a class in the child process was instantiated? Or do you suggest not starting Slanger at all and check a different assertion? This is a rather clean way of "sending a message back".

Please sign in to comment.