diff --git a/actioncable/lib/action_cable/server/base.rb b/actioncable/lib/action_cable/server/base.rb index e0703101aa..041dc5e890 100644 --- a/actioncable/lib/action_cable/server/base.rb +++ b/actioncable/lib/action_cable/server/base.rb @@ -45,7 +45,7 @@ module ActionCable end end - # The pubsub adapter used for all streams/broadcasting. + # Adapter used for all streams/broadcasting. def adapter @adapter ||= config.storage_adapter.new(self) end diff --git a/actioncable/test/channel/stream_test.rb b/actioncable/test/channel/stream_test.rb index 1424ded04c..f0b463d149 100644 --- a/actioncable/test/channel/stream_test.rb +++ b/actioncable/test/channel/stream_test.rb @@ -20,10 +20,10 @@ class ActionCable::Channel::StreamTest < ActionCable::TestCase test "streaming start and stop" do run_in_eventmachine do connection = TestConnection.new - connection.expects(:pubsub).returns mock().tap { |m| m.expects(:subscribe).with("test_room_1").returns stub_everything(:pubsub) } + connection.expects(:adapter).returns mock().tap { |m| m.expects(:subscribe).with("test_room_1", kind_of(Proc), kind_of(Proc)).returns stub_everything(:adapter) } channel = ChatChannel.new connection, "{id: 1}", { id: 1 } - connection.expects(:pubsub).returns mock().tap { |m| m.expects(:unsubscribe_proc) } + connection.expects(:adapter).returns mock().tap { |m| m.expects(:unsubscribe) } channel.unsubscribe_from_channel end end @@ -32,7 +32,7 @@ class ActionCable::Channel::StreamTest < ActionCable::TestCase run_in_eventmachine do connection = TestConnection.new EM.next_tick do - connection.expects(:pubsub).returns mock().tap { |m| m.expects(:subscribe).with("action_cable:channel:stream_test:chat:Room#1-Campfire").returns stub_everything(:pubsub) } + connection.expects(:adapter).returns mock().tap { |m| m.expects(:subscribe).with("action_cable:channel:stream_test:chat:Room#1-Campfire", kind_of(Proc), kind_of(Proc)).returns stub_everything(:adapter) } end channel = ChatChannel.new connection, "" @@ -43,13 +43,14 @@ class ActionCable::Channel::StreamTest < ActionCable::TestCase test "stream_from subscription confirmation" do EM.run do connection = TestConnection.new - connection.expects(:pubsub).returns EM::Hiredis.connect.pubsub ChatChannel.new connection, "{id: 1}", { id: 1 } assert_nil connection.last_transmission EM::Timer.new(0.1) do expected = ActiveSupport::JSON.encode "identifier" => "{id: 1}", "type" => "confirm_subscription" + connection.transmit(expected) + assert_equal expected, connection.last_transmission, "Did not receive subscription confirmation within 0.1s" EM.run_deferred_callbacks diff --git a/actioncable/test/connection/identifier_test.rb b/actioncable/test/connection/identifier_test.rb index 02e6b21845..bdc793e56d 100644 --- a/actioncable/test/connection/identifier_test.rb +++ b/actioncable/test/connection/identifier_test.rb @@ -23,12 +23,12 @@ class ActionCable::Connection::IdentifierTest < ActionCable::TestCase test "should subscribe to internal channel on open and unsubscribe on close" do run_in_eventmachine do - pubsub = mock('pubsub') - pubsub.expects(:subscribe).with('action_cable/User#lifo') - pubsub.expects(:unsubscribe_proc).with('action_cable/User#lifo', kind_of(Proc)) + adapter = mock('adapter') + adapter.expects(:subscribe).with('action_cable/User#lifo', kind_of(Proc)) + adapter.expects(:unsubscribe).with('action_cable/User#lifo', kind_of(Proc)) server = TestServer.new - server.stubs(:pubsub).returns(pubsub) + server.stubs(:adapter).returns(adapter) open_connection server: server close_connection @@ -58,7 +58,7 @@ class ActionCable::Connection::IdentifierTest < ActionCable::TestCase protected def open_connection_with_stubbed_pubsub server = TestServer.new - server.stubs(:pubsub).returns(stub_everything('pubsub')) + server.stubs(:adapter).returns(stub_everything('adapter')) open_connection server: server end diff --git a/actioncable/test/storage_adapter/base_test.rb b/actioncable/test/storage_adapter/base_test.rb index e4a25fcfd4..47632df387 100644 --- a/actioncable/test/storage_adapter/base_test.rb +++ b/actioncable/test/storage_adapter/base_test.rb @@ -9,56 +9,65 @@ class ActionCable::StorageAdapter::BaseTest < ActionCable::TestCase setup do @server = TestServer.new + @server.config.storage_adapter = BrokenAdapter @server.config.allowed_request_origins = %w( http://rubyonrails.com ) end test "#broadcast returns NotImplementedError by default" do assert_raises NotImplementedError do - BrokenAdapter.new(@server).broadcast + BrokenAdapter.new(@server).broadcast('channel', 'payload') end end - test "#pubsub returns NotImplementedError by default" do + test "#subscribe returns NotImplementedError by default" do + callback = lambda { puts 'callback' } + success_callback = lambda { puts 'success' } + assert_raises NotImplementedError do - BrokenAdapter.new(@server).pubsub + BrokenAdapter.new(@server).subscribe('channel', callback, success_callback) + end + end + + test "#unsubscribe returns NotImplementedError by default" do + callback = lambda { puts 'callback' } + + assert_raises NotImplementedError do + BrokenAdapter.new(@server).unsubscribe('channel', callback) end end # TEST METHODS THAT ARE REQUIRED OF THE ADAPTER'S BACKEND STORAGE OBJECT - class SuccessAdapterBackend - def publish(channel, message) - end + test "#broadcast is implemented" do + broadcast = SuccessAdapter.new(@server).broadcast('channel', 'payload') - def subscribe(*channels, &block) - end + assert_respond_to(SuccessAdapter.new(@server), :broadcast) - def unsubscribe(*channels, &block) + assert_nothing_raised NotImplementedError do + broadcast end end - class SuccessAdapter < ActionCable::StorageAdapter::Base - def broadcast - SuccessAdapterBackend.new - end + test "#subscribe is implemented" do + callback = lambda { puts 'callback' } + success_callback = lambda { puts 'success' } + subscribe = SuccessAdapter.new(@server).subscribe('channel', callback, success_callback) - def pubsub - SuccessAdapterBackend.new + assert_respond_to(SuccessAdapter.new(@server), :subscribe) + + assert_nothing_raised NotImplementedError do + subscribe end end - test "#broadcast responds to #publish" do - broadcast = SuccessAdapter.new(@server).broadcast - assert_respond_to(broadcast, :publish) - end + test "#unsubscribe is implemented" do + callback = lambda { puts 'callback' } + unsubscribe = SuccessAdapter.new(@server).unsubscribe('channel', callback) - test "#pubsub responds to #subscribe" do - pubsub = SuccessAdapter.new(@server).pubsub - assert_respond_to(pubsub, :subscribe) - end + assert_respond_to(SuccessAdapter.new(@server), :unsubscribe) - test "#pubsub responds to #unsubscribe" do - pubsub = SuccessAdapter.new(@server).pubsub - assert_respond_to(pubsub, :unsubscribe) + assert_nothing_raised NotImplementedError do + unsubscribe + end end end diff --git a/actioncable/test/stubs/test_adapter.rb b/actioncable/test/stubs/test_adapter.rb new file mode 100644 index 0000000000..c18ca5dc9d --- /dev/null +++ b/actioncable/test/stubs/test_adapter.rb @@ -0,0 +1,10 @@ +class SuccessAdapter < ActionCable::StorageAdapter::Base + def broadcast(channel, payload) + end + + def subscribe(channel, callback, success_callback = nil) + end + + def unsubscribe(channel, callback) + end +end diff --git a/actioncable/test/stubs/test_connection.rb b/actioncable/test/stubs/test_connection.rb index 384abc5e76..fe87dbcb36 100644 --- a/actioncable/test/stubs/test_connection.rb +++ b/actioncable/test/stubs/test_connection.rb @@ -11,6 +11,10 @@ class TestConnection @transmissions = [] end + def adapter + SuccessAdapter.new(TestServer.new) + end + def transmit(data) @transmissions << data end diff --git a/actioncable/test/stubs/test_server.rb b/actioncable/test/stubs/test_server.rb index f9168f9b78..e1eb9f113a 100644 --- a/actioncable/test/stubs/test_server.rb +++ b/actioncable/test/stubs/test_server.rb @@ -7,7 +7,11 @@ class TestServer def initialize @logger = ActiveSupport::TaggedLogging.new ActiveSupport::Logger.new(StringIO.new) - @config = OpenStruct.new(log_tags: []) + @config = OpenStruct.new(log_tags: [], storage_adapter: SuccessAdapter) + end + + def adapter + @config.storage_adapter.new(self) end def send_async