hkroger-websocket-rails 0.7.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (120) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGELOG.md +328 -0
  3. data/Gemfile +27 -0
  4. data/MIT-LICENSE +20 -0
  5. data/README.md +237 -0
  6. data/Rakefile +72 -0
  7. data/bin/thin-socketrails +45 -0
  8. data/lib/assets/javascripts/websocket_rails/abstract_connection.js.coffee +45 -0
  9. data/lib/assets/javascripts/websocket_rails/channel.js.coffee +70 -0
  10. data/lib/assets/javascripts/websocket_rails/event.js.coffee +42 -0
  11. data/lib/assets/javascripts/websocket_rails/http_connection.js.coffee +66 -0
  12. data/lib/assets/javascripts/websocket_rails/main.js +6 -0
  13. data/lib/assets/javascripts/websocket_rails/websocket_connection.js.coffee +29 -0
  14. data/lib/assets/javascripts/websocket_rails/websocket_rails.js.coffee +158 -0
  15. data/lib/config.ru +3 -0
  16. data/lib/generators/websocket_rails/install/install_generator.rb +33 -0
  17. data/lib/generators/websocket_rails/install/templates/events.rb +14 -0
  18. data/lib/generators/websocket_rails/install/templates/websocket_rails.rb +63 -0
  19. data/lib/hkroger-websocket-rails.rb +1 -0
  20. data/lib/rails/app/controllers/websocket_rails/delegation_controller.rb +13 -0
  21. data/lib/rails/config/routes.rb +7 -0
  22. data/lib/rails/tasks/websocket_rails.tasks +42 -0
  23. data/lib/spec_helpers/matchers/route_matchers.rb +65 -0
  24. data/lib/spec_helpers/matchers/trigger_matchers.rb +113 -0
  25. data/lib/spec_helpers/spec_helper_event.rb +34 -0
  26. data/lib/websocket-rails.rb +108 -0
  27. data/lib/websocket_rails/base_controller.rb +197 -0
  28. data/lib/websocket_rails/channel.rb +97 -0
  29. data/lib/websocket_rails/channel_manager.rb +55 -0
  30. data/lib/websocket_rails/configuration.rb +169 -0
  31. data/lib/websocket_rails/connection_adapters.rb +195 -0
  32. data/lib/websocket_rails/connection_adapters/http.rb +120 -0
  33. data/lib/websocket_rails/connection_adapters/web_socket.rb +36 -0
  34. data/lib/websocket_rails/connection_manager.rb +119 -0
  35. data/lib/websocket_rails/controller_factory.rb +80 -0
  36. data/lib/websocket_rails/data_store.rb +145 -0
  37. data/lib/websocket_rails/dispatcher.rb +129 -0
  38. data/lib/websocket_rails/engine.rb +26 -0
  39. data/lib/websocket_rails/event.rb +189 -0
  40. data/lib/websocket_rails/event_map.rb +184 -0
  41. data/lib/websocket_rails/event_queue.rb +33 -0
  42. data/lib/websocket_rails/internal_events.rb +37 -0
  43. data/lib/websocket_rails/logging.rb +133 -0
  44. data/lib/websocket_rails/spec_helpers.rb +3 -0
  45. data/lib/websocket_rails/synchronization.rb +182 -0
  46. data/lib/websocket_rails/user_manager.rb +276 -0
  47. data/lib/websocket_rails/version.rb +3 -0
  48. data/spec/dummy/Rakefile +7 -0
  49. data/spec/dummy/app/controllers/application_controller.rb +3 -0
  50. data/spec/dummy/app/controllers/chat_controller.rb +53 -0
  51. data/spec/dummy/app/helpers/application_helper.rb +2 -0
  52. data/spec/dummy/app/models/user.rb +2 -0
  53. data/spec/dummy/app/views/layouts/application.html.erb +14 -0
  54. data/spec/dummy/config.ru +4 -0
  55. data/spec/dummy/config/application.rb +45 -0
  56. data/spec/dummy/config/boot.rb +10 -0
  57. data/spec/dummy/config/database.yml +22 -0
  58. data/spec/dummy/config/environment.rb +5 -0
  59. data/spec/dummy/config/environments/development.rb +26 -0
  60. data/spec/dummy/config/environments/production.rb +49 -0
  61. data/spec/dummy/config/environments/test.rb +34 -0
  62. data/spec/dummy/config/events.rb +7 -0
  63. data/spec/dummy/config/initializers/backtrace_silencers.rb +7 -0
  64. data/spec/dummy/config/initializers/inflections.rb +10 -0
  65. data/spec/dummy/config/initializers/mime_types.rb +5 -0
  66. data/spec/dummy/config/initializers/secret_token.rb +7 -0
  67. data/spec/dummy/config/initializers/session_store.rb +8 -0
  68. data/spec/dummy/config/locales/en.yml +5 -0
  69. data/spec/dummy/config/routes.rb +58 -0
  70. data/spec/dummy/db/development.sqlite3 +0 -0
  71. data/spec/dummy/db/migrate/20130902222552_create_users.rb +10 -0
  72. data/spec/dummy/db/schema.rb +23 -0
  73. data/spec/dummy/db/test.sqlite3 +0 -0
  74. data/spec/dummy/log/development.log +17 -0
  75. data/spec/dummy/log/production.log +0 -0
  76. data/spec/dummy/log/server.log +0 -0
  77. data/spec/dummy/public/404.html +26 -0
  78. data/spec/dummy/public/422.html +26 -0
  79. data/spec/dummy/public/500.html +26 -0
  80. data/spec/dummy/public/favicon.ico +0 -0
  81. data/spec/dummy/public/javascripts/application.js +2 -0
  82. data/spec/dummy/public/javascripts/controls.js +965 -0
  83. data/spec/dummy/public/javascripts/dragdrop.js +974 -0
  84. data/spec/dummy/public/javascripts/effects.js +1123 -0
  85. data/spec/dummy/public/javascripts/prototype.js +6001 -0
  86. data/spec/dummy/public/javascripts/rails.js +202 -0
  87. data/spec/dummy/script/rails +6 -0
  88. data/spec/integration/connection_manager_spec.rb +135 -0
  89. data/spec/javascripts/support/jasmine.yml +52 -0
  90. data/spec/javascripts/support/jasmine_helper.rb +38 -0
  91. data/spec/javascripts/support/vendor/sinon-1.7.1.js +4343 -0
  92. data/spec/javascripts/websocket_rails/channel_spec.coffee +112 -0
  93. data/spec/javascripts/websocket_rails/event_spec.coffee +69 -0
  94. data/spec/javascripts/websocket_rails/helpers.coffee +6 -0
  95. data/spec/javascripts/websocket_rails/websocket_connection_spec.coffee +158 -0
  96. data/spec/javascripts/websocket_rails/websocket_rails_spec.coffee +274 -0
  97. data/spec/spec_helper.rb +41 -0
  98. data/spec/spec_helpers/matchers/route_matchers_spec.rb +109 -0
  99. data/spec/spec_helpers/matchers/trigger_matchers_spec.rb +247 -0
  100. data/spec/spec_helpers/spec_helper_event_spec.rb +66 -0
  101. data/spec/support/helper_methods.rb +42 -0
  102. data/spec/support/mock_web_socket.rb +41 -0
  103. data/spec/unit/base_controller_spec.rb +74 -0
  104. data/spec/unit/channel_manager_spec.rb +58 -0
  105. data/spec/unit/channel_spec.rb +169 -0
  106. data/spec/unit/connection_adapters/http_spec.rb +88 -0
  107. data/spec/unit/connection_adapters/web_socket_spec.rb +30 -0
  108. data/spec/unit/connection_adapters_spec.rb +259 -0
  109. data/spec/unit/connection_manager_spec.rb +148 -0
  110. data/spec/unit/controller_factory_spec.rb +76 -0
  111. data/spec/unit/data_store_spec.rb +106 -0
  112. data/spec/unit/dispatcher_spec.rb +203 -0
  113. data/spec/unit/event_map_spec.rb +120 -0
  114. data/spec/unit/event_queue_spec.rb +36 -0
  115. data/spec/unit/event_spec.rb +181 -0
  116. data/spec/unit/logging_spec.rb +162 -0
  117. data/spec/unit/synchronization_spec.rb +150 -0
  118. data/spec/unit/target_validator_spec.rb +88 -0
  119. data/spec/unit/user_manager_spec.rb +165 -0
  120. metadata +320 -0
@@ -0,0 +1,181 @@
1
+ require 'spec_helper'
2
+
3
+ module WebsocketRails
4
+ describe Event do
5
+ let(:encoded_message) { '["new_message",{"id":"1234","data":{"message":"this is a message"}}]' }
6
+ let(:encoded_message_string) { '["new_message",{"id":"1234","data":"this is a message"}]' }
7
+ let(:namespace_encoded_message_string) { '["product.new_message",{"id":"1234","data":"this is a message"}]' }
8
+ let(:namespace_encoded_message) { '["product.new_message",{"id":"1234","data":{"message":"this is a message"}}]' }
9
+ let(:channel_encoded_message_string) { '["new_message",{"id":"1234","channel":"awesome_channel","user_id":null,"data":"this is a message","success":null,"result":null,"token":null,"server_token":"1234"}]' }
10
+ let(:synchronizable_encoded_message) { '["new_message",{"id":"1234","data":{"message":"this is a message"},"server_token":"1234"}]' }
11
+ let(:connection) { double('connection') }
12
+ let(:wrongly_encoded_message) { '["new_message",[{"id":"1234","data":{"message":"this is a message"}}]]' }
13
+
14
+ before { connection.stub(:id).and_return(1) }
15
+
16
+ describe ".new_from_json" do
17
+ context "messages in the global namespace" do
18
+ it "should decode a new message and store it" do
19
+ event = Event.new_from_json( encoded_message, connection )
20
+ event.connection.should == connection
21
+ event.name.should == :new_message
22
+ event.namespace.should == [:global]
23
+ event.data[:message].should == 'this is a message'
24
+ end
25
+ end
26
+
27
+ context "messages in a child namespace" do
28
+ it "should store the event with the correct namesapce" do
29
+ event = Event.new_from_json( namespace_encoded_message, connection )
30
+ event.namespace.should == [:global,:product]
31
+ event.name.should == :new_message
32
+ event.data[:message].should == 'this is a message'
33
+ end
34
+ end
35
+
36
+ context "invalid messages" do
37
+ it "should return an invalid event if data is wrongly encoded" do
38
+ event = Event.new_from_json( wrongly_encoded_message, connection )
39
+ event.is_invalid?.should be_true
40
+ end
41
+ end
42
+ end
43
+
44
+ describe ".new_on_open" do
45
+ before { @event = Event.new_on_open connection, {:message => 'connected'} }
46
+
47
+ it "should create an event named :client_connected" do
48
+ @event.name.should == :client_connected
49
+ end
50
+
51
+ it "should send the connection id to the client" do
52
+ @event.data[:connection_id].should == 1
53
+ end
54
+
55
+ it "should merge the optional data with the connection id" do
56
+ @event.data[:message].should == 'connected'
57
+ end
58
+ end
59
+
60
+ describe ".new_on_close" do
61
+ it "should create an event named :client_disconnected" do
62
+ event = Event.new_on_close( connection, "optional_data" )
63
+ event.name.should == :client_disconnected
64
+ event.data.should == "optional_data"
65
+ event.connection.should == connection
66
+ end
67
+ end
68
+
69
+ describe ".new_on_error" do
70
+ it "should create an event named :client_error" do
71
+ event = Event.new_on_error( connection, "optional_data" )
72
+ event.name.should == :client_error
73
+ event.data.should == "optional_data"
74
+ event.connection.should == connection
75
+ end
76
+ end
77
+
78
+ context "new namespaced events" do
79
+ it "should store the namespace in the namespace attribute" do
80
+ event = Event.new "event", :data => {}, :connection => connection, :namespace => :product
81
+ event.namespace.should == [:global,:product]
82
+ event.name.should == :event
83
+ end
84
+
85
+ it "should store nested namespaces in the namespace attribute" do
86
+ event = Event.new "event", :data => {}, :connection => connection, :namespace => [:product,:x_ray_vision]
87
+ event.namespace.should == [:global,:product,:x_ray_vision]
88
+ event.name.should == :event
89
+ end
90
+ end
91
+
92
+ context "new channel events" do
93
+ it "should store the channel name in the channel attribute" do
94
+ event = Event.new "event", :data => {}, :connection => connection, :channel => :awesome_channel
95
+ event.channel.should == :awesome_channel
96
+ event.name.should == :event
97
+ end
98
+
99
+ it "should not raise an error if the channel name cannot be symbolized" do
100
+ expect { Event.new "event", :data => {}, :connection => connection, :channel => 5 }.to_not raise_error
101
+ event = Event.new "event", :data => {}, :connection => connection, :channel => 5
102
+ event.channel.should == :"5"
103
+ end
104
+ end
105
+
106
+ describe "#is_channel?" do
107
+ it "should return true if an event belongs to a channel" do
108
+ event = Event.new "event", :data => "data", :channel => :awesome_channel
109
+ event.is_channel?.should be_true
110
+ end
111
+ end
112
+
113
+ describe "#is_user?" do
114
+ it "returns true if the event is meant for a specific user" do
115
+ event = Event.new "event", :data => "data", :user_id => :username
116
+ event.is_user?
117
+ end
118
+ end
119
+
120
+ describe "#is_invalid?" do
121
+ it "returns true if the event name is :invalid_event" do
122
+ event = Event.new(:invalid_event)
123
+ event.is_invalid?.should be_true
124
+ end
125
+ end
126
+
127
+ describe "#is_internal?" do
128
+ it "returns true if the event is namespaced under websocket_rails" do
129
+ event = Event.new(:internal_event, :namespace => :websocket_rails)
130
+ event.is_internal?.should be_true
131
+ end
132
+ end
133
+
134
+ describe "#serialize" do
135
+ context "messages in the global namespace" do
136
+ it "should not add the global namespace to the event name" do
137
+ event = Event.new_from_json encoded_message_string, connection
138
+ raw_data = event.serialize
139
+ data = JSON.parse raw_data
140
+ data[0].should == "new_message"
141
+ end
142
+ end
143
+
144
+ context "messages in a child namespace" do
145
+ it "should add the namespace to the front of the event name" do
146
+ event = Event.new_from_json namespace_encoded_message_string, connection
147
+ raw_data = event.serialize
148
+ data = JSON.parse raw_data
149
+ data[0].should == "product.new_message"
150
+ end
151
+ end
152
+
153
+ context "messages for a channel" do
154
+ it "should add the channel name as the first element of the serialized array" do
155
+ event = Event.new_from_json channel_encoded_message_string, connection
156
+ event.serialize.should == channel_encoded_message_string
157
+ end
158
+ end
159
+
160
+ context "messages for synchronization" do
161
+ it "should include the unique server token" do
162
+ event = Event.new_from_json synchronizable_encoded_message, connection
163
+ raw_data = event.serialize
164
+ data = JSON.parse raw_data
165
+ data[1]['server_token'].should == '1234'
166
+ end
167
+ end
168
+
169
+ describe "#as_json" do
170
+ it "returns a Hash representation of the Event" do
171
+ hash = { data: { 'test' => 'test'}, channel: :awesome_channel }
172
+ event = Event.new 'test', hash
173
+ event.as_json[0].should == :test
174
+ event.as_json[1][:data].should == hash[:data]
175
+ event.as_json[1][:channel].should == hash[:channel]
176
+ end
177
+ end
178
+ end
179
+
180
+ end
181
+ end
@@ -0,0 +1,162 @@
1
+ require 'spec_helper'
2
+ require "ostruct"
3
+
4
+ module WebsocketRails
5
+ describe Logging do
6
+
7
+ class LoggedClass
8
+ include Logging
9
+ end
10
+
11
+ let(:io) { StringIO.new }
12
+ let(:object) { LoggedClass.new }
13
+
14
+ before do
15
+ WebsocketRails.config.logger = Logger.new(io)
16
+ end
17
+
18
+ describe "#info" do
19
+ it "logs the message" do
20
+ object.info "info logged"
21
+ io.string.should include("info logged")
22
+ end
23
+ end
24
+
25
+ describe "#debug" do
26
+ it "logs the message" do
27
+ object.debug "debug logged"
28
+ io.string.should include("debug logged")
29
+ end
30
+ end
31
+
32
+ describe "log_exception" do
33
+ let(:exception) { Exception.new('kaputt!').tap { |e| e.set_backtrace(['line 1', 'line 2']) } }
34
+
35
+ it "logs the exception message" do
36
+ object.log_exception(exception)
37
+ io.string.should include('kaputt!')
38
+ end
39
+
40
+ it "logs the backtrace" do
41
+ object.log_exception(exception)
42
+ io.string.should include("line 1")
43
+ io.string.should include("line 2")
44
+ end
45
+ end
46
+
47
+ context "logging an event" do
48
+ before do
49
+ data = {
50
+ namespace: :logger,
51
+ data: {message: "hello"},
52
+ connection: double('connection')
53
+ }
54
+ @event = Event.new(:logged_event, data)
55
+ end
56
+
57
+ describe "#log_event_start" do
58
+ it "logs the event information" do
59
+ object.log_event_start(@event)
60
+ io.string.should include("Started Event:")
61
+ io.string.should include("logger.logged_event")
62
+ end
63
+ end
64
+
65
+ describe "#log_event_end" do
66
+ it "logs the total time the event took to process" do
67
+ time = 12
68
+ object.log_event_end(@event, time)
69
+ io.string.should include("Event #{@event.encoded_name} Finished in #{time.to_f.to_d.to_s} seconds")
70
+ end
71
+ end
72
+
73
+ describe "#log_event" do
74
+ it "logs the start of the event" do
75
+ object.should_receive(:log_event_start).with(@event)
76
+ object.log_event(@event) { true }
77
+ end
78
+
79
+ it "logs the end of the event" do
80
+ time = Time.now
81
+ Time.stub(:now).and_return(time)
82
+ object.should_receive(:log_event_end).with(@event, 0)
83
+ object.log_event(@event) { true }
84
+ end
85
+
86
+ it "executes the block" do
87
+ executed = false
88
+ object.log_event(@event) { executed = true }
89
+ executed.should == true
90
+ end
91
+
92
+ it "logs any exceptions" do
93
+ exception = Exception.new("ouch")
94
+ object.should_receive(:log_exception).with(exception)
95
+ expect {
96
+ object.log_event(@event) { raise exception }
97
+ }.to raise_exception(exception.class, exception.message)
98
+ end
99
+ end
100
+ end
101
+
102
+ describe "#log_data?" do
103
+ before do
104
+ @hash_event = Event.new(:log_test, :data => {test: true})
105
+ @string_event = Event.new(:log_test, :data => "message")
106
+ @object_event = Event.new(:log_test, :data => OpenStruct.new)
107
+ end
108
+
109
+ it "returns true if data is an allowed type" do
110
+ object.log_data?(@hash_event).should == true
111
+ object.log_data?(@string_event).should == true
112
+ end
113
+
114
+ it "returns false if the data is not an allows type" do
115
+ object.log_data?(@object_event).should == false
116
+ end
117
+ end
118
+
119
+ describe "#log_event?" do
120
+ context "with an internal event" do
121
+ before do
122
+ @event = Event.new(:internal, :namespace => :websocket_rails)
123
+ end
124
+
125
+ context "when WebsocketRails.config.log_internal_events? is false" do
126
+ it "returns false" do
127
+ WebsocketRails.config.log_internal_events = false
128
+ object.log_event?(@event).should == false
129
+ end
130
+ end
131
+
132
+ context "when WebsocketRails.config.log_internal_events? is true" do
133
+ it "returns true" do
134
+ WebsocketRails.config.log_internal_events = true
135
+ object.log_event?(@event).should == true
136
+ end
137
+ end
138
+ end
139
+
140
+ context "with an external event" do
141
+ before do
142
+ @event = Event.new(:external)
143
+ end
144
+
145
+ context "when WebsocketRails.config.log_internal_events? is false" do
146
+ it "returns true" do
147
+ WebsocketRails.config.log_internal_events = false
148
+ object.log_event?(@event).should == true
149
+ end
150
+ end
151
+
152
+ context "when WebsocketRails.config.log_internal_events? is true" do
153
+ it "returns true" do
154
+ WebsocketRails.config.log_internal_events = true
155
+ object.log_event?(@event).should == true
156
+ end
157
+ end
158
+ end
159
+ end
160
+
161
+ end
162
+ end
@@ -0,0 +1,150 @@
1
+ require "spec_helper"
2
+ require "eventmachine"
3
+ require "ostruct"
4
+
5
+ module WebsocketRails
6
+ describe Synchronization do
7
+
8
+ around(:each) do |example|
9
+ EM.run do
10
+ Fiber.new do
11
+ @redis = Redis.new(WebsocketRails.config.redis_options)
12
+ @redis.del "websocket_rails.active_servers"
13
+ example.run
14
+ end.resume
15
+ end
16
+ end
17
+
18
+ after(:each) do
19
+ @redis.del "websocket_rails.active_servers"
20
+ EM.stop
21
+ end
22
+
23
+ let(:subject) { Synchronization.singleton }
24
+
25
+ describe "#publish" do
26
+ it "should add the serialized event to the websocket_rails.events channel" do
27
+ event = Event.new(:test_event, :channel => 'synchrony', :data => 'hello channel')
28
+ Redis.any_instance.should_receive(:publish).with("websocket_rails.events", event.serialize)
29
+
30
+ subject.publish(event)
31
+ end
32
+ end
33
+
34
+ describe "#synchronize!" do
35
+ # need to add an integration test to cover this.
36
+ end
37
+
38
+ describe "#trigger_incoming" do
39
+ context "when dispatching channel events" do
40
+ before do
41
+ @event = Event.new(:channel_event, :channel => :channel_one, :data => 'hello channel one')
42
+ end
43
+
44
+ it "triggers the event on the correct channel" do
45
+ WebsocketRails[:channel_one].should_receive(:trigger_event).with @event
46
+ subject.trigger_incoming @event
47
+ end
48
+ end
49
+
50
+ context "when dispatching user events" do
51
+ before do
52
+ @event = Event.new(:channel_event, :user_id => "username", :data => 'hello channel one')
53
+ end
54
+
55
+ context "and the user is not connected to this server" do
56
+ it "does nothing" do
57
+ subject.trigger_incoming(@event).should == nil
58
+ end
59
+ end
60
+
61
+ context "and the user is connected to this server" do
62
+ before do
63
+ @connection = double('Connection')
64
+ WebsocketRails.users["username"] = @connection
65
+ end
66
+
67
+ it "triggers the event on the correct user" do
68
+ WebsocketRails.users["username"].should_receive(:trigger).with @event
69
+ subject.trigger_incoming @event
70
+ end
71
+ end
72
+ end
73
+ end
74
+
75
+ describe "#generate_server_token" do
76
+ before do
77
+ SecureRandom.stub(:urlsafe_base64).and_return(1, 2, 3)
78
+ end
79
+
80
+ after do
81
+ @redis.del "websocket_rails.active_servers"
82
+ end
83
+
84
+ it "should generate a unique server token" do
85
+ SecureRandom.should_receive(:urlsafe_base64).at_least(1).times
86
+ subject.generate_server_token
87
+ end
88
+
89
+ it "should generate another id if the current id is already registered" do
90
+ @redis.sadd "websocket_rails.active_servers", 1
91
+ token = subject.generate_server_token
92
+ token.should == 2
93
+ end
94
+ end
95
+
96
+ describe "#register_server" do
97
+ it "should add the unique token to the active_servers key in redis" do
98
+ Redis.any_instance.should_receive(:sadd).with("websocket_rails.active_servers", "token")
99
+ subject.register_server "token"
100
+ end
101
+ end
102
+
103
+ describe "#remove_server" do
104
+ it "should remove the unique token from the active_servers key in redis" do
105
+ Redis.any_instance.should_receive(:srem).with("websocket_rails.active_servers", "token")
106
+ subject.remove_server "token"
107
+ end
108
+ end
109
+
110
+ describe "#register_user" do
111
+ before do
112
+ @connection = double('Connection')
113
+ @user = User.new
114
+ @user.attributes.update(name: 'Frank The Tank', email: 'frank@tank.com')
115
+ @user.instance_variable_set(:@new_record, false)
116
+ @user.instance_variable_set(:@destroyed, false)
117
+ @connection.stub(:user_identifier).and_return 'Frank The Tank'
118
+ @connection.stub(:user).and_return @user
119
+ end
120
+
121
+ it "stores the serialized user object in redis" do
122
+ @user.persisted?.should == true
123
+ Redis.any_instance.should_receive(:hset).with("websocket_rails.users", @connection.user_identifier, @user.as_json.to_json)
124
+ Synchronization.register_user(@connection)
125
+ end
126
+ end
127
+
128
+ describe "#destroy_user" do
129
+ it "stores the serialized user object in redis" do
130
+ Redis.any_instance.should_receive(:hdel).with("websocket_rails.users", 'user_id')
131
+ Synchronization.destroy_user('user_id')
132
+ end
133
+ end
134
+
135
+ describe "#find_user" do
136
+ it "retrieves the serialized user object in redis" do
137
+ Redis.any_instance.should_receive(:hget).with("websocket_rails.users", 'test')
138
+ Synchronization.find_user('test')
139
+ end
140
+ end
141
+
142
+ describe "#all_users" do
143
+ it "retrieves the entire serialized users hash redis" do
144
+ Redis.any_instance.should_receive(:hgetall).with("websocket_rails.users")
145
+ Synchronization.all_users
146
+ end
147
+ end
148
+
149
+ end
150
+ end