How to fix {:error, :nosession} in Phoenix LiveView tests

Tags:
  • Phoenix
  • Elixir

Published


I was writing tests for a LiveView using PhoenixTest and I kept bumping into an error that seemingly no one else was, at least in my searching.

In short, I have a LiveView with a form. On submit a resource is created and the user is redirected with push_navigate to another view.

# application code (more or less)
def handle_event("submit", %{"form" => params}, socket) do
  case AshPhoenix.Form.submit(socket.assigns.form, params: params) do
    {:ok, league} ->
      socket =
        socket
        |> push_navigate(to: league_url(league))

      {:noreply, socket}

    {:error, form} -> ...
  end
end

# test
conn
  |> MyApp.Test.Auth.login(user)
  |> visit(url)
  |> fill_in("label", with: "value")
  |> submit()

When running this test, I kept seeing a relatively inscrutable error:

** (FunctionClauseError) no function clause matching in PhoenixTest.Live.maybe_redirect/2

The following arguments were given to PhoenixTest.Live.maybe_redirect/2:

# 1
{:error, :nosession}

# 2
%PhoenixTest.Live{view: #Phoenix.LiveViewTest.View<id: ...

{:error, :nosession} features exactly once in Elixir Forum.

Cursor kept spinning uselessly. So I cloned the repos of Phoenix, LiveView, PhoenixTest. Grepping for :nosession turns out a single instance of the atom.

phoenix_live_view/lib/phoenix_live_view/test/live_view_test.ex
355:    {:error, :nosession}

Long story short, I was using push_navigate with a URL to a regular view, instead of a LiveView so the session was really not there.

Some more context can be found in this GitHub issue.