I am developing a web app with the Phoenix framework in a Docker container. Here are the relevant lines in the dockerfile for how phoenix is getting installed:
RUN git clone https://github.com/phoenixframework/phoenix
RUN cd /home/user/phoenix/installer/ && MIX_ENV=prod mix do archive.build, archive.install --force
That all works fine. I can generate a new phoenix project with the command:
mix phx.new hello_phoenix
However, when I generate a new channel with:
mix phx.gen.channel hello_channel
and add this line to the user socket file
channel "hello_channel:lobby", HelloPhoenixWeb.HelloChannelChannel
and then run
mix test
I get the following errors:
warning: Phoenix.ChannelTest.socket/2 is deprecated, please call socket/3 instead
(phoenix) lib/phoenix/test/channel_test.ex:234: Phoenix.ChannelTest."MACRO-socket"/3
(elixir) src/elixir_dispatch.erl:186: :elixir_dispatch.expand_macro_fun/6
(elixir) src/elixir_dispatch.erl:149: :elixir_dispatch.do_expand_import/6
(elixir) src/elixir_dispatch.erl:81: :elixir_dispatch.dispatch_import/5
(elixir) src/elixir_expand.erl:539: :elixir_expand.expand_arg/2
(stdlib) lists.erl:1354: :lists.mapfoldl/3
(elixir) src/elixir_expand.erl:548: :elixir_expand.expand_args/2
(elixir) src/elixir_expand.erl:646: :elixir_expand.expand_remote/7
(elixir) src/elixir_dispatch.erl:207: :elixir_dispatch.expand_quoted/6
(elixir) src/elixir_expand.erl:10: :elixir_expand.expand/2
(elixir) src/elixir_expand.erl:489: :elixir_expand.expand_block/4
(elixir) src/elixir_expand.erl:39: :elixir_expand.expand/2
(elixir) src/elixir_clauses.erl:19: :elixir_clauses.def/2
(elixir) src/elixir_def.erl:146: :elixir_def."-store_definition/10-lc$^0/1-0-"/2
(elixir) src/elixir_def.erl:146: :elixir_def.store_definition/10
test/hello_phoenix_web/channels/hello_channel_channel_test.exs:6: (module)
(elixir) src/elixir_compiler.erl:85: :elixir_compiler.dispatch/6
..
== Compilation error in file test/hello_phoenix_web/channels/hello_channel_channel_test.exs ==
** (CaseClauseError) no case clause matching: [{"/socket", HelloPhoenixWeb.UserSocket, [], [{["socket", "websocket"], {:websocket, HelloPhoenixWeb.UserSocket, [serializer: [{Phoenix.Socket.V1.JSONSerializer, "~> 1.0.0"}, {Phoenix.Socket.V2.JSONSerializer, "~> 2.0.0"}], timeout: 60000, transport_log: false, compress: false]}}]}]
(phoenix) lib/phoenix/test/channel_test.ex:240: Phoenix.ChannelTest.first_socket!/1
(phoenix) lib/phoenix/test/channel_test.ex:213: Phoenix.ChannelTest.build_socket/4
(phoenix) expanding macro: Phoenix.ChannelTest.socket/2
test/hello_phoenix_web/channels/hello_channel_channel_test.exs:8: HelloPhoenixWeb.HelloChannelChannelTest.__ex_unit_setup_1/1
(elixir) expanding macro: Kernel.|>/2
test/hello_phoenix_web/channels/hello_channel_channel_test.exs:9: HelloPhoenixWeb.HelloChannelChannelTest.__ex_unit_setup_1/1
(elixir) lib/code.ex:677: Code.require_file/2
(elixir) lib/kernel/parallel_compiler.ex:201: anonymous fn/4 in Kernel.ParallelCompiler.spawn_workers/6
Here's the code for the channel file that was generated by the mix phx.gen.channel
task:
defmodule HelloPhoenixWeb.HelloChannelChannel do
use HelloPhoenixWeb, :channel
def join("hello_channel:lobby", payload, socket) do
if authorized?(payload) do
{:ok, socket}
else
{:error, %{reason: "unauthorized"}}
end
end
# Channels can be used in a request/response fashion
# by sending replies to requests from the client
def handle_in("ping", payload, socket) do
{:reply, {:ok, payload}, socket}
end
# It is also common to receive messages from the client and
# broadcast to everyone in the current topic (hello_channel:lobby).
def handle_in("shout", payload, socket) do
broadcast socket, "shout", payload
{:noreply, socket}
end
# Add authorization logic here as required.
defp authorized?(_payload) do
true
end
end
And here's the code for the test that was generated also:
defmodule HelloPhoenixWeb.HelloChannelChannelTest do
use HelloPhoenixWeb.ChannelCase
alias HelloPhoenixWeb.HelloChannelChannel
setup do
{:ok, _, socket} =
socket("user_id", %{some: :assign})
|> subscribe_and_join(HelloChannelChannel, "hello_channel:lobby")
{:ok, socket: socket}
end
test "ping replies with status ok", %{socket: socket} do
ref = push socket, "ping", %{"hello" => "there"}
assert_reply ref, :ok, %{"hello" => "there"}
end
test "shout broadcasts to hello_channel:lobby", %{socket: socket} do
push socket, "shout", %{"hello" => "all"}
assert_broadcast "shout", %{"hello" => "all"}
end
test "broadcasts are pushed to the client", %{socket: socket} do
broadcast_from! socket, "broadcast", %{"some" => "data"}
assert_push "broadcast", %{"some" => "data"}
end
end
I have this problem with an actual project I'm working on and also with a test project I spun up to isolate the problem.
What is causing the compilation error with the test that the generator made?