Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to test the broadcast made to a channel from different channel or controller?

I have a driver channel which broadcasts their location to a vendor channel.

defmodule MyApp.DriverChannel do
    #...

    def handle_in("transmit", payload, socket) do
      MyApp.Endpoint.broadcast! "vendors:lobby", "track", payload
      {:noreply, socket}
    end
end

defmodule MyApp.DriverChannelTest do

  #....

  test "location broadcasts to vendors:lobby", %{socket: socket} do
    push socket, "transmit", %{"hello" => "all"}
    assert_broadcast "track", %{"hello" => "all"}
    # Want something like this
    # assert_broadcast "vendors:lobby", "track", %{"hello" => "all"}
  end

end

This assertion would fail, as it only checks the broadcast from DriverChannel, how to assert the broadcast made to VendorChannel, I looked through the source code, it seems like there is no option to pass a channel_name to assert_broadcast macro.

[ Another note] I also have broadcast made from controllers, if I know answer to this, I could also assert those broadcasts too! :)

like image 715
Vysakh Sreenivasan Avatar asked Oct 31 '15 14:10

Vysakh Sreenivasan


2 Answers

The new version you need self

  • to subscribe: MyApp.Endpoint.subscribe("vendors:lobby")
  • to unsubscribe: MyApp.Endpoint.unsubscribe("vendors:lobby")

if you do not 'unsubscribe' you will have a warning:

[warning] Passing a Pid to Phoenix.PubSub.subscribe is deprecated. Only the calling process may subscribe to topics

new code:

test "location broadcasts to vendors:lobby", %{socket: socket} do
  MyApp.Endpoint.subscribe("vendors:lobby")
  push socket, "transmit", %{"hello" => "all"}
  assert_broadcast "track", %{"hello" => "all"}
  assert_receive %Phoenix.Socket.Broadcast{
    topic: "vendors:lobby",
    event: "track",
    payload: %{"hello" => "all"}
  MyApp.Endpoint.unsubscribe("vendors:lobby")
end
like image 27
douarbou Avatar answered Sep 23 '22 23:09

douarbou


assert_broadcast is only for the subscribed topic, but you can subscribe directly via MyApp.Endpoint.subscribe/2 and assert_receive:

test "location broadcasts to vendors:lobby", %{socket: socket} do
  MyApp.Endpoint.subscribe(self, "vendors:lobby")
  push socket, "transmit", %{"hello" => "all"}
  assert_broadcast "track", %{"hello" => "all"}
  assert_receive %Phoenix.Socket.Broadcast{
    topic: "vendors:lobby",
    event: "track",
    payload: %{"hello" => "all"}}
end
like image 185
Chris McCord Avatar answered Sep 26 '22 23:09

Chris McCord