#ConnCase.log_in_user/1 is not available in a test setup callback

7 messages · Page 1 of 1 (latest)

rancid escarp
#

I tried to add a callback (authenticate/1) to authenticate a user before every test as follows:

defmodule XClarityWeb.ClientLiveTest do
  use XClarityWeb.ConnCase

  import Phoenix.LiveViewTest
  import XClarity.ClientsFixtures
  import XClarity.AccountsFixtures

defp create_client(_) do
    client = client_fixture()
    %{client: client}
  end

  defp authenticate(conn) do
    conn
    |> login_user(user_fixture())
  end

describe "Index" do
    setup [:create_client]

    setup %{conn: conn} do
      authenticate(conn)
    end

    test "lists all clients", %{conn: conn, client: client} do
      {:ok, _index_live, html} = live(conn, ~p"/clients")

      assert html =~ "Listing Clients"
      assert html =~ client.name
    end
...

but it failed with:

error: undefined function login_user/2 (expected XClarityWeb.ClientLiveTest to define such a function or for it to be imported, but none are available)
  test/xclarity_web/live/client_live_test.exs:19: XClarityWeb.ClientLiveTest.authenticate/1

But if I call login_user direcctly in a test example like this:

describe "Index" do
    setup [:create_client]

    # setup %{conn: conn} do
    #  authenticate(conn)
    # end

    test "lists all clients", %{conn: conn, client: client} do
      {:ok, _lv, html} =
        conn
        |> log_in_user(user_fixture())
        |> live(~p"/clients")

      assert html =~ "Listing Clients"
      assert html =~ client.name
    end

it works :(.
Why so?

tidal solstice
#

your two examples don't match, the first uses login_user the second uses log_in_user

rancid escarp
#

My bad, that was a typo, nice catch :).
After changiung that as follows:

defp create_client(_) do
    client = client_fixture()
    %{client: client}
  end

  defp authenticate(conn) do
    conn
    |> log_in_user(user_fixture())
  end

  describe "Index" do
    setup [:create_client]

    setup %{conn: conn} do
      authenticate(conn)
    end

    test "lists all clients", %{conn: conn, client: client} do
      {:ok, _index_live, html} = live(conn, ~p"/clients")

      assert html =~ "Listing Clients"
      assert html =~ client.name
    end
...

it fails with this error though :(.

#
1) test Index lists all clients (XClarityWeb.ClientLiveTest)
     test/xclarity_web/live/client_live_test.exs:29
     ** (RuntimeError) expected ExUnit setup callback in XClarityWeb.ClientLiveTest to return :ok | keyword | map, got %Plug.Conn{adapter: {Plug.Adapters.Test.Conn, :...}, assigns: %{}, body_params: %Plug.Conn.Unfetched{aspect: :body_params}, cookies: %Plug.Conn.Unfetched{aspect: :cookies}, halted: false, host: "www.example.com", method: "GET", owner: #PID<0.387.0>, params: %Plug.Conn.Unfetched{aspect: :params}, path_info: [], path_params: %{}, port: 80, private: %{phoenix_recycled: true, plug_session: %{"user_token" => <<62, 25, 231, 4, 33, 94, 26, 65, 192, 191, 62, 203, 55, 90, 221, 1, 29, 250, 75, 101, 167, 51, 131, 181, 10, 157, 186, 19, 246, 43, 205, 143>>}, plug_session_fetch: :done, plug_session_info: :write, plug_skip_csrf_protection: true}, query_params: %Plug.Conn.Unfetched{aspect: :query_params}, query_string: "", remote_ip: {127, 0, 0, 1}, req_cookies: %Plug.Conn.Unfetched{aspect: :cookies}, req_headers: [], request_path: "/", resp_body: nil, resp_cookies: %{}, resp_headers: [{"cache-control", "max-age=0, private, must-revalidate"}], scheme: :http, script_name: [], secret_key_base: nil, state: :unset, status: nil} instead
     stacktrace:
       (ex_unit 1.15.2) lib/ex_unit/callbacks.ex:727: ExUnit.Callbacks.raise_merge_failed!/3
       XClarityWeb.ClientLiveTest.__ex_unit_describe_0/1

What's wrong here?

#

the newly added authenticate function does return an updated conn, right? Maybe smth wrong with the call of setup callback?

#

Ah, after modifying the callback authenticate to return a map as follows:

defp authenticate(conn) do
    conn =
      conn
      |> log_in_user(user_fixture())

    %{conn: conn}
  end

the test passed :).

brazen pike
#

If you change your authenticate function to this

defp authenticate(%{conn: conn}) do
    conn =
      conn
      |> log_in_user(user_fixture())

    %{conn: conn}
end

Then you can simplify your setup call to this setup [:create_client, :authenticate].