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?
Phoenix framework 1.4 is still in development state so bugs are pretty much not surprising. Phoenix framwork 1.3.x is current stable version, you should use that. And if you know what your are doing with 1.4-dev build than you should raise a issue on Phoenix Framework github repo.