te_chris

te_chris

How to test a live_session on_mount handler that sets assigns

I’m running into an edge case with phoenix testing. I’ve got an on_mount handler behaving like a plug which creates a db session for a given client:

defmodule SgWeb.InitSessionId do
  @moduledoc """
  Adds the DB session ID to the assigns
  """
  import Phoenix.Component
  alias Sg.Sessions

  def on_mount(:default, _params, %{"client_id" => client_id}, socket) do
    session =
      case Sessions.get_session_by_client_id(client_id) do
        nil ->
          {:ok, session} = Sessions.create_session(%{client_id: client_id})
          session

        existing_session ->
          existing_session
      end

    {:cont, assign(socket, session_id: session.id)}
  end
end

However, whenever I try to test this as one would a plug, the assign function blows up and tells me I need to use render_component. I understand the logic, generally, but there has to be a way around this - I’m literally following a use case described in the docs in this instance (Phoenix.LiveView — Phoenix LiveView v0.19.5). Is there an easy way to mock a socket/assigns without triggering the exceptions?

Marked As Solved

sodapopcan

sodapopcan

Have you tried this?

socket = %Phoenix.LiveView.Socket{}

It seemed to do the trick for me.

Also Liked

sodapopcan

sodapopcan

I should be clear that I was just testing out your example and think Chris’ suggestion is the way to go.

Personally, I forgo unit testing these hooks and just test their effects in each LiveView they’re used in. I make a helper for this, kind of like how phx_gen_auth does with its generated register_and_log_in_user test helper. But obviously if you want a unit test that’s absolutely fine, I’m just sharing!

Speaking of phx_gen_auth, it actually does generate unit tests for its hooks that look like your tests! For example:

test "authenticates current_user based on a valid user_token ", %{conn: conn, user: user} do
  user_token = Accounts.generate_user_session_token(user)
  session = conn |> put_session(:user_token, user_token) |> get_session()

  {:cont, updated_socket} =
    UserAuth.on_mount(:ensure_authenticated, %{}, session, %LiveView.Socket{})

  assert updated_socket.assigns.current_user.id == user.id
end

Where Next?

Popular in Questions Top

JDanielMartinez
Hi! May someone helps me, please! I have two apps into an umbrella project: the first one is Database, which manages queries, and the se...
New
gshaw
What is the idiomatic way of matching for not nil in Elixir? E.g., First way: defp halt_if_not_signed_in(conn, signed_in_account) when...
New
JorisKok
I have a server on AWS, and was running a load test using artillery. When looking at the Phoenix dashboard I see the Ports going to 100% ...
New
sacepums
Hey guys. I'm new to elixir and im really stocked about it. But I ran into a bit of problem - I need to convert a date sting, for examp...
New
fireproofsocks
Forgive me if this is obvious, but how does one delete a database record WITHOUT selecting it first? https://hexdocs.pm/ecto/Ecto.Repo.h...
New
Codball
Mix format works fine if run from the cmd. I’ve followed this to facilitate the implementation into VSC which involves downloading an ext...
New
Qqwy
Original source of discussion: This topic on the Pragmatic Programmers' Functional Web Development with Elixir, OTP, and Phoenix forum. ...
New
romenigld
I am trying to run a deploy with docker and I successfully runned with this command: docker build -t romenigld/blog-prod . but when I t...
New
vrod
I am using the Starship cross-shell prompt – it seems pretty nice, but I get some errors: [WARN] - (starship::utils): Executing command ...
New
lanycrost
Hi everyone! I need implement if…else if…else condition from my elixir code, and anymore of this control flow structures not work proper...
New

Other popular topics Top

JDanielMartinez
Hi! May someone helps me, please! I have two apps into an umbrella project: the first one is Database, which manages queries, and the se...
New
vonH
In asking this question I am more interested about the expressiveness of the language itself and less concerned about the availability of...
New
yawaramin
In the Dialyzer docs ( http://erlang.org/doc/man/dialyzer.html#requesting-or-suppressing-warnings-in-source-files ), there is a way to tu...
New
malloryerik
Hi, this is for people who, like me, have had some friction using .html.heex templates in VSCode. The solution seems to be, in a hyphena...
New
SoCreat
i’m a new one to elixir which editor can i use vs code? or atom? Thanks! :smiley:
New
Jim
As a follow up to my earlier question: I have the code compiling and running but not getting a successful login from the rest server. ...
New
rms.mrcs
Hi, I need to transform a list of numbers into a map where the keys are the indexes and the values are the original values of the list....
New
stefanluptak
Hello everybody, usually, I use a 29" ultra-wide monitor for VSCode which can easily accomodate explorer (files panel) + file with code ...
New
msaraiva
Surface is an experimental library built on top of Phoenix LiveView and its new LiveComponent API that aims to provide a more declarative...
564 42633 214
New
joeerl
Hello again - after a longish gap I’ve decided I really must dig into Elixir and see what’s been happening here - so I have a few questio...
New

We're in Beta

About us Mission Statement