action-cable-testing 0.2.0 → 0.3.0
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.
- checksums.yaml +5 -5
 - data/CHANGELOG.md +8 -0
 - data/README.md +54 -0
 - data/lib/action_cable/channel/test_case.rb +7 -5
 - data/lib/action_cable/connection/test_case.rb +192 -0
 - data/lib/action_cable/testing.rb +6 -0
 - data/lib/action_cable/testing/version.rb +1 -1
 - data/lib/rspec/rails/example/channel_example_group.rb +11 -0
 - data/lib/rspec/rails/matchers/action_cable.rb +2 -2
 - metadata +4 -3
 
    
        checksums.yaml
    CHANGED
    
    | 
         @@ -1,7 +1,7 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            ---
         
     | 
| 
       2 
     | 
    
         
            -
             
     | 
| 
       3 
     | 
    
         
            -
              metadata.gz:  
     | 
| 
       4 
     | 
    
         
            -
              data.tar.gz:  
     | 
| 
      
 2 
     | 
    
         
            +
            SHA256:
         
     | 
| 
      
 3 
     | 
    
         
            +
              metadata.gz: f485ca6094981aea2459acc0a1334d79855b20180fd7866e4bbb073d97d9d75a
         
     | 
| 
      
 4 
     | 
    
         
            +
              data.tar.gz: a350c77463c57478ada51df21acdeab8a4ef4621abe7dad12a07347a3820c4f3
         
     | 
| 
       5 
5 
     | 
    
         
             
            SHA512:
         
     | 
| 
       6 
     | 
    
         
            -
              metadata.gz:  
     | 
| 
       7 
     | 
    
         
            -
              data.tar.gz:  
     | 
| 
      
 6 
     | 
    
         
            +
              metadata.gz: 166cd3cfd3481b90e4d67d3c1b2348010e399e762d5278e198de9d3b254babac01287ddfa288c0aa8c7ebd1402e538e2c34bc83a5ebda4214f3105c6288d84c5
         
     | 
| 
      
 7 
     | 
    
         
            +
              data.tar.gz: a3065fa172d0a0777dc057c68b17e5b12d1b89a4c105b9566b8a44cca3d37db713242982f9d1d9d465a5088b758fdf1b393bd0845f819dbeacac92109d1a8aa1
         
     | 
    
        data/CHANGELOG.md
    CHANGED
    
    | 
         @@ -1,5 +1,13 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            # Change log
         
     | 
| 
       2 
2 
     | 
    
         | 
| 
      
 3 
     | 
    
         
            +
            ## master
         
     | 
| 
      
 4 
     | 
    
         
            +
             
     | 
| 
      
 5 
     | 
    
         
            +
            ## 0.3.0
         
     | 
| 
      
 6 
     | 
    
         
            +
             
     | 
| 
      
 7 
     | 
    
         
            +
            - Add connection unit-testing utilities. ([@palkan][])
         
     | 
| 
      
 8 
     | 
    
         
            +
             
     | 
| 
      
 9 
     | 
    
         
            +
              See https://github.com/palkan/action-cable-testing/pull/6
         
     | 
| 
      
 10 
     | 
    
         
            +
             
     | 
| 
       3 
11 
     | 
    
         
             
            ## 0.2.0
         
     | 
| 
       4 
12 
     | 
    
         | 
| 
       5 
13 
     | 
    
         
             
            - Update minitest's `assert_broadcast_on` and `assert_broadcasts` matchers to support a record as an argument. ([@thesmartnik][])
         
     | 
    
        data/README.md
    CHANGED
    
    | 
         @@ -156,6 +156,43 @@ class ChatChannelTest < ActionCable::Channel::TestCase 
     | 
|
| 
       156 
156 
     | 
    
         
             
            end
         
     | 
| 
       157 
157 
     | 
    
         
             
            ```
         
     | 
| 
       158 
158 
     | 
    
         | 
| 
      
 159 
     | 
    
         
            +
            ### Connection Testing
         
     | 
| 
      
 160 
     | 
    
         
            +
             
     | 
| 
      
 161 
     | 
    
         
            +
            Connection unit tests are written as follows:
         
     | 
| 
      
 162 
     | 
    
         
            +
            1. First, one uses the `connect` method to simulate connection.
         
     | 
| 
      
 163 
     | 
    
         
            +
            2. Then, one asserts whether the current state is as expected (e.g. identifiers).
         
     | 
| 
      
 164 
     | 
    
         
            +
             
     | 
| 
      
 165 
     | 
    
         
            +
            For example:
         
     | 
| 
      
 166 
     | 
    
         
            +
             
     | 
| 
      
 167 
     | 
    
         
            +
            ```ruby
         
     | 
| 
      
 168 
     | 
    
         
            +
            module ApplicationCable
         
     | 
| 
      
 169 
     | 
    
         
            +
              class ConnectionTest < ActionCable::Connection::TestCase
         
     | 
| 
      
 170 
     | 
    
         
            +
                def test_connects_with_cookies
         
     | 
| 
      
 171 
     | 
    
         
            +
                  # Simulate a connection
         
     | 
| 
      
 172 
     | 
    
         
            +
                  connect cookies: { user_id: users[:john].id }
         
     | 
| 
      
 173 
     | 
    
         
            +
             
     | 
| 
      
 174 
     | 
    
         
            +
                  # Asserts that the connection identifier is correct
         
     | 
| 
      
 175 
     | 
    
         
            +
                  assert_equal "John", connection.user.name
         
     | 
| 
      
 176 
     | 
    
         
            +
              end
         
     | 
| 
      
 177 
     | 
    
         
            +
             
     | 
| 
      
 178 
     | 
    
         
            +
              def test_does_not_connect_without_user
         
     | 
| 
      
 179 
     | 
    
         
            +
                assert_reject_connection do
         
     | 
| 
      
 180 
     | 
    
         
            +
                  connect
         
     | 
| 
      
 181 
     | 
    
         
            +
                end
         
     | 
| 
      
 182 
     | 
    
         
            +
              end
         
     | 
| 
      
 183 
     | 
    
         
            +
            end
         
     | 
| 
      
 184 
     | 
    
         
            +
            ```
         
     | 
| 
      
 185 
     | 
    
         
            +
             
     | 
| 
      
 186 
     | 
    
         
            +
            You can also provide additional information about underlying HTTP request:
         
     | 
| 
      
 187 
     | 
    
         
            +
             
     | 
| 
      
 188 
     | 
    
         
            +
            ```ruby
         
     | 
| 
      
 189 
     | 
    
         
            +
            def test_connect_with_headers_and_query_string
         
     | 
| 
      
 190 
     | 
    
         
            +
              connect "/cable?user_id=1", headers: { "X-API-TOKEN" => 'secret-my' }
         
     | 
| 
      
 191 
     | 
    
         
            +
             
     | 
| 
      
 192 
     | 
    
         
            +
              assert_equal connection.user_id, "1"
         
     | 
| 
      
 193 
     | 
    
         
            +
            end
         
     | 
| 
      
 194 
     | 
    
         
            +
            ```
         
     | 
| 
      
 195 
     | 
    
         
            +
             
     | 
| 
       159 
196 
     | 
    
         
             
            ### RSpec Usage
         
     | 
| 
       160 
197 
     | 
    
         | 
| 
       161 
198 
     | 
    
         
             
            First, you need to have [rspec-rails](https://github.com/rspec/rspec-rails) installed.
         
     | 
| 
         @@ -227,6 +264,23 @@ RSpec.describe ChatChannel, type: :channel do 
     | 
|
| 
       227 
264 
     | 
    
         
             
            end
         
     | 
| 
       228 
265 
     | 
    
         
             
            ```
         
     | 
| 
       229 
266 
     | 
    
         | 
| 
      
 267 
     | 
    
         
            +
            And, of course, connections:
         
     | 
| 
      
 268 
     | 
    
         
            +
             
     | 
| 
      
 269 
     | 
    
         
            +
            ```ruby
         
     | 
| 
      
 270 
     | 
    
         
            +
            require "rails_helper"
         
     | 
| 
      
 271 
     | 
    
         
            +
             
     | 
| 
      
 272 
     | 
    
         
            +
            RSpec.describe ApplicationCable::Connection, type: :channel do
         
     | 
| 
      
 273 
     | 
    
         
            +
              it "successfully connects" do
         
     | 
| 
      
 274 
     | 
    
         
            +
                connect "/cable", headers: { "X-USER-ID" => "325" }
         
     | 
| 
      
 275 
     | 
    
         
            +
                expect(connection.user_id).to eq "325"
         
     | 
| 
      
 276 
     | 
    
         
            +
              end
         
     | 
| 
      
 277 
     | 
    
         
            +
             
     | 
| 
      
 278 
     | 
    
         
            +
              it "rejects connection" do
         
     | 
| 
      
 279 
     | 
    
         
            +
                expect { connect "/cable" }.to have_rejected_connection
         
     | 
| 
      
 280 
     | 
    
         
            +
              end
         
     | 
| 
      
 281 
     | 
    
         
            +
            end
         
     | 
| 
      
 282 
     | 
    
         
            +
            ```
         
     | 
| 
      
 283 
     | 
    
         
            +
             
     | 
| 
       230 
284 
     | 
    
         
             
            #### Shared contexts to switch between adapters
         
     | 
| 
       231 
285 
     | 
    
         | 
| 
       232 
286 
     | 
    
         
             
            Sometimes you may want to use _real_ Action Cable adapter instead of the test one (for example, in Capybara-like tests).
         
     | 
| 
         @@ -38,6 +38,10 @@ module ActionCable 
     | 
|
| 
       38 
38 
     | 
    
         
             
                  def streams
         
     | 
| 
       39 
39 
     | 
    
         
             
                    @_streams ||= []
         
     | 
| 
       40 
40 
     | 
    
         
             
                  end
         
     | 
| 
      
 41 
     | 
    
         
            +
             
     | 
| 
      
 42 
     | 
    
         
            +
                  # Make periodic timers no-op
         
     | 
| 
      
 43 
     | 
    
         
            +
                  def start_periodic_timers; end
         
     | 
| 
      
 44 
     | 
    
         
            +
                  alias stop_periodic_timers start_periodic_timers
         
     | 
| 
       41 
45 
     | 
    
         
             
                end
         
     | 
| 
       42 
46 
     | 
    
         | 
| 
       43 
47 
     | 
    
         
             
                class ConnectionStub
         
     | 
| 
         @@ -80,7 +84,7 @@ module ActionCable 
     | 
|
| 
       80 
84 
     | 
    
         
             
                #       assert subscription.confirmed?
         
     | 
| 
       81 
85 
     | 
    
         
             
                #
         
     | 
| 
       82 
86 
     | 
    
         
             
                #       # Asserts that the channel subscribes connection to a stream
         
     | 
| 
       83 
     | 
    
         
            -
                #        
     | 
| 
      
 87 
     | 
    
         
            +
                #       assert_equal "chat_1", streams.last
         
     | 
| 
       84 
88 
     | 
    
         
             
                #     end
         
     | 
| 
       85 
89 
     | 
    
         
             
                #
         
     | 
| 
       86 
90 
     | 
    
         
             
                #     def test_does_not_subscribe_without_room_number
         
     | 
| 
         @@ -137,6 +141,7 @@ module ActionCable 
     | 
|
| 
       137 
141 
     | 
    
         | 
| 
       138 
142 
     | 
    
         
             
                    include ActiveSupport::Testing::ConstantLookup
         
     | 
| 
       139 
143 
     | 
    
         
             
                    include ActionCable::TestHelper
         
     | 
| 
      
 144 
     | 
    
         
            +
                    include ActionCable::Connection::TestCase::Behavior
         
     | 
| 
       140 
145 
     | 
    
         | 
| 
       141 
146 
     | 
    
         
             
                    CHANNEL_IDENTIFIER = "test_stub"
         
     | 
| 
       142 
147 
     | 
    
         | 
| 
         @@ -191,6 +196,7 @@ module ActionCable 
     | 
|
| 
       191 
196 
     | 
    
         | 
| 
       192 
197 
     | 
    
         
             
                    # Subsribe to the channel under test. Optionally pass subscription parameters as a Hash.
         
     | 
| 
       193 
198 
     | 
    
         
             
                    def subscribe(params = {})
         
     | 
| 
      
 199 
     | 
    
         
            +
                      @connection ||= stub_connection
         
     | 
| 
       194 
200 
     | 
    
         
             
                      # NOTE: Rails < 5.0.1 calls subscribe_to_channel during #initialize.
         
     | 
| 
       195 
201 
     | 
    
         
             
                      #       We have to stub before it
         
     | 
| 
       196 
202 
     | 
    
         
             
                      @subscription = self.class.channel_class.allocate
         
     | 
| 
         @@ -209,10 +215,6 @@ module ActionCable 
     | 
|
| 
       209 
215 
     | 
    
         
             
                      subscription.perform_action(data.stringify_keys.merge("action" => action.to_s))
         
     | 
| 
       210 
216 
     | 
    
         
             
                    end
         
     | 
| 
       211 
217 
     | 
    
         | 
| 
       212 
     | 
    
         
            -
                    def connection # :nodoc:
         
     | 
| 
       213 
     | 
    
         
            -
                      @connection ||= stub_connection
         
     | 
| 
       214 
     | 
    
         
            -
                    end
         
     | 
| 
       215 
     | 
    
         
            -
             
     | 
| 
       216 
218 
     | 
    
         
             
                    # Returns messages transmitted into channel
         
     | 
| 
       217 
219 
     | 
    
         
             
                    def transmissions
         
     | 
| 
       218 
220 
     | 
    
         
             
                      # Return only directly sent message (via #transmit)
         
     | 
| 
         @@ -0,0 +1,192 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # frozen_string_literal: true
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            require "active_support"
         
     | 
| 
      
 4 
     | 
    
         
            +
            require "active_support/test_case"
         
     | 
| 
      
 5 
     | 
    
         
            +
            require "active_support/core_ext/hash/indifferent_access"
         
     | 
| 
      
 6 
     | 
    
         
            +
            require "action_dispatch"
         
     | 
| 
      
 7 
     | 
    
         
            +
            require "action_dispatch/testing/test_request"
         
     | 
| 
      
 8 
     | 
    
         
            +
             
     | 
| 
      
 9 
     | 
    
         
            +
            module ActionCable
         
     | 
| 
      
 10 
     | 
    
         
            +
              module Connection
         
     | 
| 
      
 11 
     | 
    
         
            +
                class NonInferrableConnectionError < ::StandardError
         
     | 
| 
      
 12 
     | 
    
         
            +
                  def initialize(name)
         
     | 
| 
      
 13 
     | 
    
         
            +
                    super "Unable to determine the connection to test from #{name}. " +
         
     | 
| 
      
 14 
     | 
    
         
            +
                      "You'll need to specify it using tests YourConnection in your " +
         
     | 
| 
      
 15 
     | 
    
         
            +
                      "test case definition."
         
     | 
| 
      
 16 
     | 
    
         
            +
                  end
         
     | 
| 
      
 17 
     | 
    
         
            +
                end
         
     | 
| 
      
 18 
     | 
    
         
            +
             
     | 
| 
      
 19 
     | 
    
         
            +
                module Assertions
         
     | 
| 
      
 20 
     | 
    
         
            +
                  # Asserts that the connection is rejected (via +reject_unauthorized_connection+).
         
     | 
| 
      
 21 
     | 
    
         
            +
                  #
         
     | 
| 
      
 22 
     | 
    
         
            +
                  #   # Asserts that connection without user_id fails
         
     | 
| 
      
 23 
     | 
    
         
            +
                  #   assert_reject_connection { connect cookies: { user_id: '' } }
         
     | 
| 
      
 24 
     | 
    
         
            +
                  def assert_reject_connection(&block)
         
     | 
| 
      
 25 
     | 
    
         
            +
                    res =
         
     | 
| 
      
 26 
     | 
    
         
            +
                      begin
         
     | 
| 
      
 27 
     | 
    
         
            +
                        block.call
         
     | 
| 
      
 28 
     | 
    
         
            +
                        false
         
     | 
| 
      
 29 
     | 
    
         
            +
                      rescue ActionCable::Connection::Authorization::UnauthorizedError
         
     | 
| 
      
 30 
     | 
    
         
            +
                        true
         
     | 
| 
      
 31 
     | 
    
         
            +
                      end
         
     | 
| 
      
 32 
     | 
    
         
            +
             
     | 
| 
      
 33 
     | 
    
         
            +
                    assert res, "Expected to reject connection but no rejection were made"
         
     | 
| 
      
 34 
     | 
    
         
            +
                  end
         
     | 
| 
      
 35 
     | 
    
         
            +
                end
         
     | 
| 
      
 36 
     | 
    
         
            +
             
     | 
| 
      
 37 
     | 
    
         
            +
                class TestRequest < ActionDispatch::TestRequest
         
     | 
| 
      
 38 
     | 
    
         
            +
                  attr_reader :cookie_jar
         
     | 
| 
      
 39 
     | 
    
         
            +
             
     | 
| 
      
 40 
     | 
    
         
            +
                  module CookiesStub
         
     | 
| 
      
 41 
     | 
    
         
            +
                    # Stub signed cookies, we don't need to test encryption here
         
     | 
| 
      
 42 
     | 
    
         
            +
                    def signed
         
     | 
| 
      
 43 
     | 
    
         
            +
                      self
         
     | 
| 
      
 44 
     | 
    
         
            +
                    end
         
     | 
| 
      
 45 
     | 
    
         
            +
                  end
         
     | 
| 
      
 46 
     | 
    
         
            +
             
     | 
| 
      
 47 
     | 
    
         
            +
                  def cookie_jar=(val)
         
     | 
| 
      
 48 
     | 
    
         
            +
                    @cookie_jar = val.tap do |h|
         
     | 
| 
      
 49 
     | 
    
         
            +
                      h.singleton_class.include(CookiesStub)
         
     | 
| 
      
 50 
     | 
    
         
            +
                    end
         
     | 
| 
      
 51 
     | 
    
         
            +
                  end
         
     | 
| 
      
 52 
     | 
    
         
            +
                end
         
     | 
| 
      
 53 
     | 
    
         
            +
             
     | 
| 
      
 54 
     | 
    
         
            +
                module TestConnection
         
     | 
| 
      
 55 
     | 
    
         
            +
                  attr_reader :logger, :request
         
     | 
| 
      
 56 
     | 
    
         
            +
             
     | 
| 
      
 57 
     | 
    
         
            +
                  def initialize(path, cookies, headers)
         
     | 
| 
      
 58 
     | 
    
         
            +
                    @logger = ActiveSupport::TaggedLogging.new ActiveSupport::Logger.new(StringIO.new)
         
     | 
| 
      
 59 
     | 
    
         
            +
             
     | 
| 
      
 60 
     | 
    
         
            +
                    uri = URI.parse(path)
         
     | 
| 
      
 61 
     | 
    
         
            +
                    env = {
         
     | 
| 
      
 62 
     | 
    
         
            +
                      "QUERY_STRING" => uri.query,
         
     | 
| 
      
 63 
     | 
    
         
            +
                      "PATH_INFO" => uri.path
         
     | 
| 
      
 64 
     | 
    
         
            +
                    }.merge(build_headers(headers))
         
     | 
| 
      
 65 
     | 
    
         
            +
             
     | 
| 
      
 66 
     | 
    
         
            +
                    @request = TestRequest.create(env)
         
     | 
| 
      
 67 
     | 
    
         
            +
                    @request.cookie_jar = cookies.with_indifferent_access
         
     | 
| 
      
 68 
     | 
    
         
            +
                  end
         
     | 
| 
      
 69 
     | 
    
         
            +
             
     | 
| 
      
 70 
     | 
    
         
            +
                  def build_headers(headers)
         
     | 
| 
      
 71 
     | 
    
         
            +
                    headers.each_with_object({}) do |(k, v), obj|
         
     | 
| 
      
 72 
     | 
    
         
            +
                      k = k.upcase
         
     | 
| 
      
 73 
     | 
    
         
            +
                      k.tr!("-", "_")
         
     | 
| 
      
 74 
     | 
    
         
            +
                      obj["HTTP_#{k}"] = v
         
     | 
| 
      
 75 
     | 
    
         
            +
                    end
         
     | 
| 
      
 76 
     | 
    
         
            +
                  end
         
     | 
| 
      
 77 
     | 
    
         
            +
                end
         
     | 
| 
      
 78 
     | 
    
         
            +
             
     | 
| 
      
 79 
     | 
    
         
            +
                # Superclass for Action Cable connection unit tests.
         
     | 
| 
      
 80 
     | 
    
         
            +
                #
         
     | 
| 
      
 81 
     | 
    
         
            +
                # == Basic example
         
     | 
| 
      
 82 
     | 
    
         
            +
                #
         
     | 
| 
      
 83 
     | 
    
         
            +
                # Unit tests are written as follows:
         
     | 
| 
      
 84 
     | 
    
         
            +
                # 1. First, one uses the +connect+ method to simulate connection.
         
     | 
| 
      
 85 
     | 
    
         
            +
                # 2. Then, one asserts whether the current state is as expected (e.g. identifiers).
         
     | 
| 
      
 86 
     | 
    
         
            +
                #
         
     | 
| 
      
 87 
     | 
    
         
            +
                # For example:
         
     | 
| 
      
 88 
     | 
    
         
            +
                #
         
     | 
| 
      
 89 
     | 
    
         
            +
                #   module ApplicationCable
         
     | 
| 
      
 90 
     | 
    
         
            +
                #     class ConnectionTest < ActionCable::Connection::TestCase
         
     | 
| 
      
 91 
     | 
    
         
            +
                #       def test_connects_with_cookies
         
     | 
| 
      
 92 
     | 
    
         
            +
                #         # Simulate a connection
         
     | 
| 
      
 93 
     | 
    
         
            +
                #         connect cookies: { user_id: users[:john].id }
         
     | 
| 
      
 94 
     | 
    
         
            +
                #
         
     | 
| 
      
 95 
     | 
    
         
            +
                #         # Asserts that the connection identifier is correct
         
     | 
| 
      
 96 
     | 
    
         
            +
                #         assert_equal "John", connection.user.name
         
     | 
| 
      
 97 
     | 
    
         
            +
                #     end
         
     | 
| 
      
 98 
     | 
    
         
            +
                #
         
     | 
| 
      
 99 
     | 
    
         
            +
                #     def test_does_not_connect_without_user
         
     | 
| 
      
 100 
     | 
    
         
            +
                #       assert_reject_connection do
         
     | 
| 
      
 101 
     | 
    
         
            +
                #         connect
         
     | 
| 
      
 102 
     | 
    
         
            +
                #       end
         
     | 
| 
      
 103 
     | 
    
         
            +
                #     end
         
     | 
| 
      
 104 
     | 
    
         
            +
                #   end
         
     | 
| 
      
 105 
     | 
    
         
            +
                #
         
     | 
| 
      
 106 
     | 
    
         
            +
                # You can also provide additional information about underlying HTTP request:
         
     | 
| 
      
 107 
     | 
    
         
            +
                #   def test_connect_with_headers_and_query_string
         
     | 
| 
      
 108 
     | 
    
         
            +
                #     connect "/cable?user_id=1", headers: { "X-API-TOKEN" => 'secret-my' }
         
     | 
| 
      
 109 
     | 
    
         
            +
                #
         
     | 
| 
      
 110 
     | 
    
         
            +
                #     assert_equal connection.user_id, "1"
         
     | 
| 
      
 111 
     | 
    
         
            +
                #   end
         
     | 
| 
      
 112 
     | 
    
         
            +
                #
         
     | 
| 
      
 113 
     | 
    
         
            +
                # == Connection is automatically inferred
         
     | 
| 
      
 114 
     | 
    
         
            +
                #
         
     | 
| 
      
 115 
     | 
    
         
            +
                # ActionCable::Connection::TestCase will automatically infer the connection under test
         
     | 
| 
      
 116 
     | 
    
         
            +
                # from the test class name. If the channel cannot be inferred from the test
         
     | 
| 
      
 117 
     | 
    
         
            +
                # class name, you can explicitly set it with +tests+.
         
     | 
| 
      
 118 
     | 
    
         
            +
                #
         
     | 
| 
      
 119 
     | 
    
         
            +
                #   class ConnectionTest < ActionCable::Connection::TestCase
         
     | 
| 
      
 120 
     | 
    
         
            +
                #     tests ApplicationCable::Connection
         
     | 
| 
      
 121 
     | 
    
         
            +
                #   end
         
     | 
| 
      
 122 
     | 
    
         
            +
                #
         
     | 
| 
      
 123 
     | 
    
         
            +
                class TestCase < ActiveSupport::TestCase
         
     | 
| 
      
 124 
     | 
    
         
            +
                  module Behavior
         
     | 
| 
      
 125 
     | 
    
         
            +
                    extend ActiveSupport::Concern
         
     | 
| 
      
 126 
     | 
    
         
            +
             
     | 
| 
      
 127 
     | 
    
         
            +
                    include ActiveSupport::Testing::ConstantLookup
         
     | 
| 
      
 128 
     | 
    
         
            +
                    include Assertions
         
     | 
| 
      
 129 
     | 
    
         
            +
             
     | 
| 
      
 130 
     | 
    
         
            +
                    included do
         
     | 
| 
      
 131 
     | 
    
         
            +
                      class_attribute :_connection_class
         
     | 
| 
      
 132 
     | 
    
         
            +
             
     | 
| 
      
 133 
     | 
    
         
            +
                      attr_reader :connection
         
     | 
| 
      
 134 
     | 
    
         
            +
             
     | 
| 
      
 135 
     | 
    
         
            +
                      ActiveSupport.run_load_hooks(:action_cable_connection_test_case, self)
         
     | 
| 
      
 136 
     | 
    
         
            +
                    end
         
     | 
| 
      
 137 
     | 
    
         
            +
             
     | 
| 
      
 138 
     | 
    
         
            +
                    module ClassMethods
         
     | 
| 
      
 139 
     | 
    
         
            +
                      def tests(connection)
         
     | 
| 
      
 140 
     | 
    
         
            +
                        case connection
         
     | 
| 
      
 141 
     | 
    
         
            +
                        when String, Symbol
         
     | 
| 
      
 142 
     | 
    
         
            +
                          self._connection_class = connection.to_s.camelize.constantize
         
     | 
| 
      
 143 
     | 
    
         
            +
                        when Module
         
     | 
| 
      
 144 
     | 
    
         
            +
                          self._connection_class = connection
         
     | 
| 
      
 145 
     | 
    
         
            +
                        else
         
     | 
| 
      
 146 
     | 
    
         
            +
                          raise NonInferrableConnectionError.new(connection)
         
     | 
| 
      
 147 
     | 
    
         
            +
                        end
         
     | 
| 
      
 148 
     | 
    
         
            +
                      end
         
     | 
| 
      
 149 
     | 
    
         
            +
             
     | 
| 
      
 150 
     | 
    
         
            +
                      def connection_class
         
     | 
| 
      
 151 
     | 
    
         
            +
                        if connection = self._connection_class
         
     | 
| 
      
 152 
     | 
    
         
            +
                          connection
         
     | 
| 
      
 153 
     | 
    
         
            +
                        else
         
     | 
| 
      
 154 
     | 
    
         
            +
                          tests determine_default_connection(name)
         
     | 
| 
      
 155 
     | 
    
         
            +
                        end
         
     | 
| 
      
 156 
     | 
    
         
            +
                      end
         
     | 
| 
      
 157 
     | 
    
         
            +
             
     | 
| 
      
 158 
     | 
    
         
            +
                      def determine_default_connection(name)
         
     | 
| 
      
 159 
     | 
    
         
            +
                        connection = determine_constant_from_test_name(name) do |constant|
         
     | 
| 
      
 160 
     | 
    
         
            +
                          Class === constant && constant < ActionCable::Connection::Base
         
     | 
| 
      
 161 
     | 
    
         
            +
                        end
         
     | 
| 
      
 162 
     | 
    
         
            +
                        raise NonInferrableConnectionError.new(name) if connection.nil?
         
     | 
| 
      
 163 
     | 
    
         
            +
                        connection
         
     | 
| 
      
 164 
     | 
    
         
            +
                      end
         
     | 
| 
      
 165 
     | 
    
         
            +
                    end
         
     | 
| 
      
 166 
     | 
    
         
            +
             
     | 
| 
      
 167 
     | 
    
         
            +
                    # Performs connection attempt (i.e. calls #connect method).
         
     | 
| 
      
 168 
     | 
    
         
            +
                    #
         
     | 
| 
      
 169 
     | 
    
         
            +
                    # Accepts request path as the first argument and cookies and headers as options.
         
     | 
| 
      
 170 
     | 
    
         
            +
                    def connect(path = "/cable", cookies: {}, headers: {})
         
     | 
| 
      
 171 
     | 
    
         
            +
                      connection = self.class.connection_class.allocate
         
     | 
| 
      
 172 
     | 
    
         
            +
                      connection.singleton_class.include(TestConnection)
         
     | 
| 
      
 173 
     | 
    
         
            +
                      connection.send(:initialize, path, cookies, headers)
         
     | 
| 
      
 174 
     | 
    
         
            +
                      connection.connect if connection.respond_to?(:connect)
         
     | 
| 
      
 175 
     | 
    
         
            +
             
     | 
| 
      
 176 
     | 
    
         
            +
                      # Only set instance variable if connected successfully
         
     | 
| 
      
 177 
     | 
    
         
            +
                      @connection = connection
         
     | 
| 
      
 178 
     | 
    
         
            +
                    end
         
     | 
| 
      
 179 
     | 
    
         
            +
             
     | 
| 
      
 180 
     | 
    
         
            +
                    # Disconnect the connection under test (i.e. calls #disconnect)
         
     | 
| 
      
 181 
     | 
    
         
            +
                    def disconnect
         
     | 
| 
      
 182 
     | 
    
         
            +
                      raise "Must be connected!" if connection.nil?
         
     | 
| 
      
 183 
     | 
    
         
            +
             
     | 
| 
      
 184 
     | 
    
         
            +
                      connection.disconnect if connection.respond_to?(:disconnect)
         
     | 
| 
      
 185 
     | 
    
         
            +
                      @connection = nil
         
     | 
| 
      
 186 
     | 
    
         
            +
                    end
         
     | 
| 
      
 187 
     | 
    
         
            +
                  end
         
     | 
| 
      
 188 
     | 
    
         
            +
             
     | 
| 
      
 189 
     | 
    
         
            +
                  include Behavior
         
     | 
| 
      
 190 
     | 
    
         
            +
                end
         
     | 
| 
      
 191 
     | 
    
         
            +
              end
         
     | 
| 
      
 192 
     | 
    
         
            +
            end
         
     | 
    
        data/lib/action_cable/testing.rb
    CHANGED
    
    
| 
         @@ -27,6 +27,17 @@ if defined?(ActionCable) 
     | 
|
| 
       27 
27 
     | 
    
         
             
                      def channel_class
         
     | 
| 
       28 
28 
     | 
    
         
             
                        described_class
         
     | 
| 
       29 
29 
     | 
    
         
             
                      end
         
     | 
| 
      
 30 
     | 
    
         
            +
             
     | 
| 
      
 31 
     | 
    
         
            +
                      # @private
         
     | 
| 
      
 32 
     | 
    
         
            +
                      def connection_class
         
     | 
| 
      
 33 
     | 
    
         
            +
                        raise "Described class is not a Connection class" unless
         
     | 
| 
      
 34 
     | 
    
         
            +
                          described_class <= ::ActionCable::Connection::Base
         
     | 
| 
      
 35 
     | 
    
         
            +
                        described_class
         
     | 
| 
      
 36 
     | 
    
         
            +
                      end
         
     | 
| 
      
 37 
     | 
    
         
            +
                    end
         
     | 
| 
      
 38 
     | 
    
         
            +
             
     | 
| 
      
 39 
     | 
    
         
            +
                    def have_rejected_connection
         
     | 
| 
      
 40 
     | 
    
         
            +
                      raise_error(::ActionCable::Connection::Authorization::UnauthorizedError)
         
     | 
| 
       30 
41 
     | 
    
         
             
                    end
         
     | 
| 
       31 
42 
     | 
    
         
             
                  end
         
     | 
| 
       32 
43 
     | 
    
         
             
                end
         
     | 
| 
         @@ -7,7 +7,7 @@ module RSpec 
     | 
|
| 
       7 
7 
     | 
    
         
             
                  #
         
     | 
| 
       8 
8 
     | 
    
         
             
                  # @api private
         
     | 
| 
       9 
9 
     | 
    
         
             
                  module ActionCable
         
     | 
| 
       10 
     | 
    
         
            -
                    # rubocop: disable  
     | 
| 
      
 10 
     | 
    
         
            +
                    # rubocop: disable Metrics/ClassLength
         
     | 
| 
       11 
11 
     | 
    
         
             
                    # @private
         
     | 
| 
       12 
12 
     | 
    
         
             
                    class HaveBroadcastedTo < RSpec::Matchers::BuiltIn::BaseMatcher
         
     | 
| 
       13 
13 
     | 
    
         
             
                      def initialize(target, channel:)
         
     | 
| 
         @@ -167,7 +167,7 @@ module RSpec 
     | 
|
| 
       167 
167 
     | 
    
         
             
                        raise ArgumentError, error_msg
         
     | 
| 
       168 
168 
     | 
    
         
             
                      end
         
     | 
| 
       169 
169 
     | 
    
         
             
                    end
         
     | 
| 
       170 
     | 
    
         
            -
                    # rubocop: enable  
     | 
| 
      
 170 
     | 
    
         
            +
                    # rubocop: enable Metrics/ClassLength
         
     | 
| 
       171 
171 
     | 
    
         
             
                  end
         
     | 
| 
       172 
172 
     | 
    
         | 
| 
       173 
173 
     | 
    
         
             
                  # @api public
         
     | 
    
        metadata
    CHANGED
    
    | 
         @@ -1,14 +1,14 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            --- !ruby/object:Gem::Specification
         
     | 
| 
       2 
2 
     | 
    
         
             
            name: action-cable-testing
         
     | 
| 
       3 
3 
     | 
    
         
             
            version: !ruby/object:Gem::Version
         
     | 
| 
       4 
     | 
    
         
            -
              version: 0. 
     | 
| 
      
 4 
     | 
    
         
            +
              version: 0.3.0
         
     | 
| 
       5 
5 
     | 
    
         
             
            platform: ruby
         
     | 
| 
       6 
6 
     | 
    
         
             
            authors:
         
     | 
| 
       7 
7 
     | 
    
         
             
            - Vladimir Dementyev
         
     | 
| 
       8 
8 
     | 
    
         
             
            autorequire: 
         
     | 
| 
       9 
9 
     | 
    
         
             
            bindir: bin
         
     | 
| 
       10 
10 
     | 
    
         
             
            cert_chain: []
         
     | 
| 
       11 
     | 
    
         
            -
            date:  
     | 
| 
      
 11 
     | 
    
         
            +
            date: 2018-03-02 00:00:00.000000000 Z
         
     | 
| 
       12 
12 
     | 
    
         
             
            dependencies:
         
     | 
| 
       13 
13 
     | 
    
         
             
            - !ruby/object:Gem::Dependency
         
     | 
| 
       14 
14 
     | 
    
         
             
              name: actioncable
         
     | 
| 
         @@ -148,6 +148,7 @@ files: 
     | 
|
| 
       148 
148 
     | 
    
         
             
            - README.md
         
     | 
| 
       149 
149 
     | 
    
         
             
            - lib/action-cable-testing.rb
         
     | 
| 
       150 
150 
     | 
    
         
             
            - lib/action_cable/channel/test_case.rb
         
     | 
| 
      
 151 
     | 
    
         
            +
            - lib/action_cable/connection/test_case.rb
         
     | 
| 
       151 
152 
     | 
    
         
             
            - lib/action_cable/subscription_adapter/test.rb
         
     | 
| 
       152 
153 
     | 
    
         
             
            - lib/action_cable/test_case.rb
         
     | 
| 
       153 
154 
     | 
    
         
             
            - lib/action_cable/test_helper.rb
         
     | 
| 
         @@ -182,7 +183,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement 
     | 
|
| 
       182 
183 
     | 
    
         
             
                  version: '0'
         
     | 
| 
       183 
184 
     | 
    
         
             
            requirements: []
         
     | 
| 
       184 
185 
     | 
    
         
             
            rubyforge_project: 
         
     | 
| 
       185 
     | 
    
         
            -
            rubygems_version: 2. 
     | 
| 
      
 186 
     | 
    
         
            +
            rubygems_version: 2.7.4
         
     | 
| 
       186 
187 
     | 
    
         
             
            signing_key: 
         
     | 
| 
       187 
188 
     | 
    
         
             
            specification_version: 4
         
     | 
| 
       188 
189 
     | 
    
         
             
            summary: Testing utils for Action Cable
         
     |