diff options
Diffstat (limited to 'actioncable/test/channel')
-rw-r--r-- | actioncable/test/channel/base_test.rb | 184 | ||||
-rw-r--r-- | actioncable/test/channel/broadcasting_test.rb | 29 | ||||
-rw-r--r-- | actioncable/test/channel/naming_test.rb | 10 | ||||
-rw-r--r-- | actioncable/test/channel/periodic_timers_test.rb | 40 | ||||
-rw-r--r-- | actioncable/test/channel/rejection_test.rb | 25 | ||||
-rw-r--r-- | actioncable/test/channel/stream_test.rb | 80 |
6 files changed, 368 insertions, 0 deletions
diff --git a/actioncable/test/channel/base_test.rb b/actioncable/test/channel/base_test.rb new file mode 100644 index 0000000000..d41bf3064b --- /dev/null +++ b/actioncable/test/channel/base_test.rb @@ -0,0 +1,184 @@ +require 'test_helper' +require 'stubs/test_connection' +require 'stubs/room' + +class ActionCable::Channel::BaseTest < ActiveSupport::TestCase + class ActionCable::Channel::Base + def kick + @last_action = [ :kick ] + end + + def topic + end + end + + class BasicChannel < ActionCable::Channel::Base + def chatters + @last_action = [ :chatters ] + end + end + + class ChatChannel < BasicChannel + attr_reader :room, :last_action + after_subscribe :toggle_subscribed + after_unsubscribe :toggle_subscribed + + def initialize(*) + @subscribed = false + super + end + + def subscribed + @room = Room.new params[:id] + @actions = [] + end + + def unsubscribed + @room = nil + end + + def toggle_subscribed + @subscribed = !@subscribed + end + + def leave + @last_action = [ :leave ] + end + + def speak(data) + @last_action = [ :speak, data ] + end + + def topic(data) + @last_action = [ :topic, data ] + end + + def subscribed? + @subscribed + end + + def get_latest + transmit data: 'latest' + end + + def receive + @last_action = [ :receive ] + end + + private + def rm_rf + @last_action = [ :rm_rf ] + end + end + + setup do + @user = User.new "lifo" + @connection = TestConnection.new(@user) + @channel = ChatChannel.new @connection, "{id: 1}", { id: 1 } + end + + test "should subscribe to a channel on initialize" do + assert_equal 1, @channel.room.id + end + + test "on subscribe callbacks" do + assert @channel.subscribed + end + + test "channel params" do + assert_equal({ id: 1 }, @channel.params) + end + + test "unsubscribing from a channel" do + assert @channel.room + assert @channel.subscribed? + + @channel.unsubscribe_from_channel + + assert ! @channel.room + assert ! @channel.subscribed? + end + + test "connection identifiers" do + assert_equal @user.name, @channel.current_user.name + end + + test "callable action without any argument" do + @channel.perform_action 'action' => :leave + assert_equal [ :leave ], @channel.last_action + end + + test "callable action with arguments" do + data = { 'action' => :speak, 'content' => "Hello World" } + + @channel.perform_action data + assert_equal [ :speak, data ], @channel.last_action + end + + test "should not dispatch a private method" do + @channel.perform_action 'action' => :rm_rf + assert_nil @channel.last_action + end + + test "should not dispatch a public method defined on Base" do + @channel.perform_action 'action' => :kick + assert_nil @channel.last_action + end + + test "should dispatch a public method defined on Base and redefined on channel" do + data = { 'action' => :topic, 'content' => "This is Sparta!" } + + @channel.perform_action data + assert_equal [ :topic, data ], @channel.last_action + end + + test "should dispatch calling a public method defined in an ancestor" do + @channel.perform_action 'action' => :chatters + assert_equal [ :chatters ], @channel.last_action + end + + test "should dispatch receive action when perform_action is called with empty action" do + data = { 'content' => 'hello' } + @channel.perform_action data + assert_equal [ :receive ], @channel.last_action + end + + test "transmitting data" do + @channel.perform_action 'action' => :get_latest + + expected = ActiveSupport::JSON.encode "identifier" => "{id: 1}", "message" => { "data" => "latest" } + assert_equal expected, @connection.last_transmission + end + + test "subscription confirmation" do + expected = ActiveSupport::JSON.encode "identifier" => "{id: 1}", "type" => "confirm_subscription" + assert_equal expected, @connection.last_transmission + end + + test "actions available on Channel" do + available_actions = %w(room last_action subscribed unsubscribed toggle_subscribed leave speak subscribed? get_latest receive chatters topic).to_set + assert_equal available_actions, ChatChannel.action_methods + end + + test "invalid action on Channel" do + assert_logged("Unable to process ActionCable::Channel::BaseTest::ChatChannel#invalid_action") do + @channel.perform_action 'action' => :invalid_action + end + end + + private + def assert_logged(message) + old_logger = @connection.logger + log = StringIO.new + @connection.instance_variable_set(:@logger, Logger.new(log)) + + begin + yield + + log.rewind + assert_match message, log.read + ensure + @connection.instance_variable_set(:@logger, old_logger) + end + end +end diff --git a/actioncable/test/channel/broadcasting_test.rb b/actioncable/test/channel/broadcasting_test.rb new file mode 100644 index 0000000000..1de04243e5 --- /dev/null +++ b/actioncable/test/channel/broadcasting_test.rb @@ -0,0 +1,29 @@ +require 'test_helper' +require 'stubs/test_connection' +require 'stubs/room' + +class ActionCable::Channel::BroadcastingTest < ActiveSupport::TestCase + class ChatChannel < ActionCable::Channel::Base + end + + setup do + @connection = TestConnection.new + end + + test "broadcasts_to" do + ActionCable.stubs(:server).returns mock().tap { |m| m.expects(:broadcast).with('action_cable:channel:broadcasting_test:chat:Room#1-Campfire', "Hello World") } + ChatChannel.broadcast_to(Room.new(1), "Hello World") + end + + test "broadcasting_for with an object" do + assert_equal "Room#1-Campfire", ChatChannel.broadcasting_for(Room.new(1)) + end + + test "broadcasting_for with an array" do + assert_equal "Room#1-Campfire:Room#2-Campfire", ChatChannel.broadcasting_for([ Room.new(1), Room.new(2) ]) + end + + test "broadcasting_for with a string" do + assert_equal "hello", ChatChannel.broadcasting_for("hello") + end +end diff --git a/actioncable/test/channel/naming_test.rb b/actioncable/test/channel/naming_test.rb new file mode 100644 index 0000000000..89ef6ad8b0 --- /dev/null +++ b/actioncable/test/channel/naming_test.rb @@ -0,0 +1,10 @@ +require 'test_helper' + +class ActionCable::Channel::NamingTest < ActiveSupport::TestCase + class ChatChannel < ActionCable::Channel::Base + end + + test "channel_name" do + assert_equal "action_cable:channel:naming_test:chat", ChatChannel.channel_name + end +end diff --git a/actioncable/test/channel/periodic_timers_test.rb b/actioncable/test/channel/periodic_timers_test.rb new file mode 100644 index 0000000000..1590a12f09 --- /dev/null +++ b/actioncable/test/channel/periodic_timers_test.rb @@ -0,0 +1,40 @@ +require 'test_helper' +require 'stubs/test_connection' +require 'stubs/room' + +class ActionCable::Channel::PeriodicTimersTest < ActiveSupport::TestCase + class ChatChannel < ActionCable::Channel::Base + periodically -> { ping }, every: 5 + periodically :send_updates, every: 1 + + private + def ping + end + end + + setup do + @connection = TestConnection.new + end + + test "periodic timers definition" do + timers = ChatChannel.periodic_timers + + assert_equal 2, timers.size + + first_timer = timers[0] + assert_kind_of Proc, first_timer[0] + assert_equal 5, first_timer[1][:every] + + second_timer = timers[1] + assert_equal :send_updates, second_timer[0] + assert_equal 1, second_timer[1][:every] + end + + test "timer start and stop" do + EventMachine::PeriodicTimer.expects(:new).times(2).returns(true) + channel = ChatChannel.new @connection, "{id: 1}", { id: 1 } + + channel.expects(:stop_periodic_timers).once + channel.unsubscribe_from_channel + end +end diff --git a/actioncable/test/channel/rejection_test.rb b/actioncable/test/channel/rejection_test.rb new file mode 100644 index 0000000000..aa93396d44 --- /dev/null +++ b/actioncable/test/channel/rejection_test.rb @@ -0,0 +1,25 @@ +require 'test_helper' +require 'stubs/test_connection' +require 'stubs/room' + +class ActionCable::Channel::RejectionTest < ActiveSupport::TestCase + class SecretChannel < ActionCable::Channel::Base + def subscribed + reject if params[:id] > 0 + end + end + + setup do + @user = User.new "lifo" + @connection = TestConnection.new(@user) + end + + test "subscription rejection" do + @connection.expects(:subscriptions).returns mock().tap { |m| m.expects(:remove_subscription).with instance_of(SecretChannel) } + @channel = SecretChannel.new @connection, "{id: 1}", { id: 1 } + + expected = ActiveSupport::JSON.encode "identifier" => "{id: 1}", "type" => "reject_subscription" + assert_equal expected, @connection.last_transmission + end + +end diff --git a/actioncable/test/channel/stream_test.rb b/actioncable/test/channel/stream_test.rb new file mode 100644 index 0000000000..1424ded04c --- /dev/null +++ b/actioncable/test/channel/stream_test.rb @@ -0,0 +1,80 @@ +require 'test_helper' +require 'stubs/test_connection' +require 'stubs/room' + +class ActionCable::Channel::StreamTest < ActionCable::TestCase + class ChatChannel < ActionCable::Channel::Base + def subscribed + if params[:id] + @room = Room.new params[:id] + stream_from "test_room_#{@room.id}" + end + end + + def send_confirmation + transmit_subscription_confirmation + end + + end + + 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) } + channel = ChatChannel.new connection, "{id: 1}", { id: 1 } + + connection.expects(:pubsub).returns mock().tap { |m| m.expects(:unsubscribe_proc) } + channel.unsubscribe_from_channel + end + end + + test "stream_for" do + 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) } + end + + channel = ChatChannel.new connection, "" + channel.stream_for Room.new(1) + end + end + + 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" + assert_equal expected, connection.last_transmission, "Did not receive subscription confirmation within 0.1s" + + EM.run_deferred_callbacks + EM.stop + end + end + end + + test "subscription confirmation should only be sent out once" do + EM.run do + connection = TestConnection.new + connection.stubs(:pubsub).returns EM::Hiredis.connect.pubsub + + channel = ChatChannel.new connection, "test_channel" + channel.send_confirmation + channel.send_confirmation + + EM.run_deferred_callbacks + + expected = ActiveSupport::JSON.encode "identifier" => "test_channel", "type" => "confirm_subscription" + assert_equal expected, connection.last_transmission, "Did not receive subscription confirmation" + + assert_equal 1, connection.transmissions.size + EM.stop + end + end + +end |