-
-
Notifications
You must be signed in to change notification settings - Fork 1k
Add Action Cable testing #2113
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Add Action Cable testing #2113
Changes from all commits
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,216 @@ | ||
@rails_post_6 | ||
Feature: channel spec | ||
benoittgt marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
Channel specs are marked by `:type => :channel` or if you have set | ||
`config.infer_spec_type_from_file_location!` by placing them in `spec/channels`. | ||
|
||
A channel spec is a thin wrapper for an ActionCable::Channel::TestCase, and includes all | ||
of the behavior and assertions that it provides, in addition to RSpec's own | ||
behavior and expectations. | ||
|
||
It also includes helpers from ActionCable::Connection::TestCase to make it possible to | ||
test connection behavior. | ||
|
||
Background: | ||
Given action cable testing is available | ||
And a file named "app/channels/chat_channel.rb" with: | ||
"""ruby | ||
class ChatChannel < ApplicationCable::Channel | ||
def subscribed | ||
reject unless params[:room_id].present? | ||
end | ||
|
||
def speak(data) | ||
ActionCable.server.broadcast( | ||
"chat_#{params[:room_id]}", text: data['message'] | ||
) | ||
end | ||
|
||
def echo(data) | ||
data.delete("action") | ||
transmit data | ||
end | ||
end | ||
""" | ||
|
||
Scenario: simple passing example | ||
Given a file named "spec/channels/chat_channel_spec.rb" with: | ||
"""ruby | ||
require "rails_helper" | ||
|
||
RSpec.describe ChatChannel, :type => :channel do | ||
it "successfully subscribes" do | ||
subscribe room_id: 42 | ||
expect(subscription).to be_confirmed | ||
end | ||
end | ||
""" | ||
When I run `rspec spec/channels/chat_channel_spec.rb` | ||
Then the example should pass | ||
|
||
Scenario: verifying that subscription is rejected | ||
Given a file named "spec/channels/chat_channel_spec.rb" with: | ||
"""ruby | ||
require "rails_helper" | ||
|
||
RSpec.describe ChatChannel, :type => :channel do | ||
it "rejects subscription" do | ||
subscribe room_id: nil | ||
expect(subscription).to be_rejected | ||
end | ||
end | ||
""" | ||
When I run `rspec spec/channels/chat_channel_spec.rb` | ||
Then the example should pass | ||
|
||
Scenario: performing actions and checking transmissions | ||
Given a file named "spec/channels/chat_channel_spec.rb" with: | ||
"""ruby | ||
require "rails_helper" | ||
|
||
RSpec.describe ChatChannel, :type => :channel do | ||
it "successfully subscribes" do | ||
subscribe room_id: 42 | ||
|
||
perform :echo, foo: 'bar' | ||
expect(transmissions.last).to eq('foo' => 'bar') | ||
end | ||
end | ||
""" | ||
When I run `rspec spec/channels/chat_channel_spec.rb` | ||
Then the example should pass | ||
|
||
Scenario: successful connection with url params | ||
Given a file named "app/channels/application_cable/connection.rb" with: | ||
"""ruby | ||
class ApplicationCable::Connection < ActionCable::Connection::Base | ||
identified_by :user_id | ||
|
||
def connect | ||
self.user_id = request.params[:user_id] | ||
reject_unauthorized_connection unless user_id.present? | ||
end | ||
end | ||
""" | ||
And a file named "spec/channels/connection_spec.rb" with: | ||
"""ruby | ||
require "rails_helper" | ||
|
||
RSpec.describe ApplicationCable::Connection, :type => :channel do | ||
it "successfully connects" do | ||
connect "/cable?user_id=323" | ||
expect(connection.user_id).to eq "323" | ||
end | ||
end | ||
""" | ||
When I run `rspec spec/channels/connection_spec.rb` | ||
Then the example should pass | ||
|
||
Scenario: successful connection with cookies | ||
Given a file named "app/channels/application_cable/connection.rb" with: | ||
"""ruby | ||
class ApplicationCable::Connection < ActionCable::Connection::Base | ||
identified_by :user_id | ||
|
||
def connect | ||
self.user_id = cookies.signed[:user_id] | ||
reject_unauthorized_connection unless user_id.present? | ||
end | ||
end | ||
""" | ||
And a file named "spec/channels/connection_spec.rb" with: | ||
"""ruby | ||
require "rails_helper" | ||
|
||
RSpec.describe ApplicationCable::Connection, :type => :channel do | ||
it "successfully connects" do | ||
cookies.signed[:user_id] = "324" | ||
|
||
connect "/cable" | ||
expect(connection.user_id).to eq "324" | ||
end | ||
end | ||
""" | ||
When I run `rspec spec/channels/connection_spec.rb` | ||
Then the example should pass | ||
|
||
Scenario: successful connection with headers | ||
Given a file named "app/channels/application_cable/connection.rb" with: | ||
"""ruby | ||
class ApplicationCable::Connection < ActionCable::Connection::Base | ||
identified_by :user_id | ||
|
||
def connect | ||
self.user_id = request.headers["x-user-id"] | ||
reject_unauthorized_connection unless user_id.present? | ||
end | ||
end | ||
""" | ||
And a file named "spec/channels/connection_spec.rb" with: | ||
"""ruby | ||
require "rails_helper" | ||
|
||
RSpec.describe ApplicationCable::Connection, :type => :channel do | ||
it "successfully connects" do | ||
connect "/cable", headers: { "X-USER-ID" => "325" } | ||
expect(connection.user_id).to eq "325" | ||
end | ||
end | ||
""" | ||
When I run `rspec spec/channels/connection_spec.rb` | ||
Then the example should pass | ||
|
||
Scenario: rejected connection | ||
Given a file named "app/channels/application_cable/connection.rb" with: | ||
"""ruby | ||
class ApplicationCable::Connection < ActionCable::Connection::Base | ||
identified_by :user_id | ||
|
||
def connect | ||
self.user_id = request.params[:user_id] | ||
reject_unauthorized_connection unless user_id.present? | ||
end | ||
end | ||
""" | ||
And a file named "spec/channels/connection_spec.rb" with: | ||
"""ruby | ||
require "rails_helper" | ||
|
||
RSpec.describe ApplicationCable::Connection, :type => :channel do | ||
it "rejects connection" do | ||
expect { connect "/cable?user_id=" }.to have_rejected_connection | ||
end | ||
end | ||
""" | ||
When I run `rspec spec/channels/connection_spec.rb` | ||
Then the example should pass | ||
|
||
Scenario: disconnect connection | ||
Given a file named "app/channels/application_cable/connection.rb" with: | ||
"""ruby | ||
class ApplicationCable::Connection < ActionCable::Connection::Base | ||
identified_by :user_id | ||
|
||
def connect | ||
self.user_id = request.params[:user_id] | ||
reject_unauthorized_connection unless user_id.present? | ||
end | ||
|
||
def disconnect | ||
$stdout.puts "User #{user_id} disconnected" | ||
end | ||
end | ||
""" | ||
And a file named "spec/channels/connection_spec.rb" with: | ||
"""ruby | ||
require "rails_helper" | ||
|
||
RSpec.describe ApplicationCable::Connection, :type => :channel do | ||
it "disconnects" do | ||
connect "/cable?user_id=42" | ||
expect { disconnect }.to output(/User 42 disconnected/).to_stdout | ||
end | ||
end | ||
""" | ||
When I run `rspec spec/channels/connection_spec.rb` | ||
Then the example should pass |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,151 @@ | ||
@rails_post_6 | ||
Feature: have_broadcasted matcher | ||
benoittgt marked this conversation as resolved.
Show resolved
Hide resolved
benoittgt marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
The `have_broadcasted_to` (also aliased as `broadcast_to`) matcher is used to check if a message has been broadcasted to a given stream. | ||
|
||
Background: | ||
Given action cable testing is available | ||
|
||
Scenario: Checking stream name | ||
Given a file named "spec/models/broadcaster_spec.rb" with: | ||
"""ruby | ||
require "rails_helper" | ||
|
||
RSpec.describe "broadcasting" do | ||
it "matches with stream name" do | ||
expect { | ||
ActionCable.server.broadcast( | ||
"notifications", text: 'Hello!' | ||
) | ||
}.to have_broadcasted_to("notifications") | ||
end | ||
end | ||
""" | ||
When I run `rspec spec/models/broadcaster_spec.rb` | ||
Then the examples should all pass | ||
|
||
Scenario: Checking passed message to stream | ||
Given a file named "spec/models/broadcaster_spec.rb" with: | ||
"""ruby | ||
require "rails_helper" | ||
|
||
RSpec.describe "broadcasting" do | ||
it "matches with message" do | ||
expect { | ||
ActionCable.server.broadcast( | ||
"notifications", text: 'Hello!' | ||
) | ||
}.to have_broadcasted_to("notifications").with(text: 'Hello!') | ||
end | ||
end | ||
""" | ||
When I run `rspec spec/models/broadcaster_spec.rb` | ||
Then the examples should all pass | ||
|
||
Scenario: Checking that message passed to stream matches | ||
Given a file named "spec/models/broadcaster_spec.rb" with: | ||
"""ruby | ||
require "rails_helper" | ||
|
||
RSpec.describe "broadcasting" do | ||
it "matches with message" do | ||
expect { | ||
ActionCable.server.broadcast( | ||
"notifications", text: 'Hello!', user_id: 12 | ||
) | ||
}.to have_broadcasted_to("notifications").with(a_hash_including(text: 'Hello!')) | ||
end | ||
end | ||
""" | ||
When I run `rspec spec/models/broadcaster_spec.rb` | ||
Then the examples should all pass | ||
|
||
Scenario: Checking passed message with block | ||
Given a file named "spec/models/broadcaster_spec.rb" with: | ||
"""ruby | ||
require "rails_helper" | ||
|
||
RSpec.describe "broadcasting" do | ||
it "matches with message" do | ||
expect { | ||
ActionCable.server.broadcast( | ||
"notifications", text: 'Hello!', user_id: 12 | ||
) | ||
}.to have_broadcasted_to("notifications").with { |data| | ||
expect(data['user_id']).to eq 12 | ||
} | ||
end | ||
end | ||
""" | ||
When I run `rspec spec/models/broadcaster_spec.rb` | ||
Then the examples should all pass | ||
|
||
Scenario: Using alias method | ||
Given a file named "spec/models/broadcaster_spec.rb" with: | ||
"""ruby | ||
require "rails_helper" | ||
|
||
RSpec.describe "broadcasting" do | ||
it "matches with stream name" do | ||
expect { | ||
ActionCable.server.broadcast( | ||
"notifications", text: 'Hello!' | ||
) | ||
}.to broadcast_to("notifications") | ||
end | ||
end | ||
""" | ||
When I run `rspec spec/models/broadcaster_spec.rb` | ||
Then the examples should all pass | ||
|
||
Scenario: Checking broadcast to a record | ||
Given a file named "spec/channels/chat_channel_spec.rb" with: | ||
"""ruby | ||
require "rails_helper" | ||
|
||
RSpec.describe ChatChannel, :type => :channel do | ||
it "successfully subscribes" do | ||
user = User.new(42) | ||
|
||
expect { | ||
ChatChannel.broadcast_to(user, text: 'Hi') | ||
}.to have_broadcasted_to(user) | ||
end | ||
end | ||
""" | ||
And a file named "app/models/user.rb" with: | ||
"""ruby | ||
class User < Struct.new(:name) | ||
def to_gid_param | ||
name | ||
end | ||
end | ||
""" | ||
When I run `rspec spec/channels/chat_channel_spec.rb` | ||
Then the example should pass | ||
|
||
Scenario: Checking broadcast to a record in non-channel spec | ||
Given a file named "spec/models/broadcaster_spec.rb" with: | ||
"""ruby | ||
require "rails_helper" | ||
|
||
RSpec.describe "broadcasting" do | ||
it "matches with stream name" do | ||
user = User.new(42) | ||
|
||
expect { | ||
ChatChannel.broadcast_to(user, text: 'Hi') | ||
}.to broadcast_to(ChatChannel.broadcasting_for(user)) | ||
end | ||
end | ||
""" | ||
And a file named "app/models/user.rb" with: | ||
"""ruby | ||
class User < Struct.new(:name) | ||
def to_gid_param | ||
name | ||
end | ||
end | ||
""" | ||
When I run `rspec spec/models/broadcaster_spec.rb` | ||
Then the example should pass |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.