Test fixtures and session helpers for host applications.
ExUnit only
These compile into your production build because they live in lib/, but
they exist solely for tests and are not part of the runtime API. Nothing
here is a supported thing to call from application code.
Why this ships
Every host was writing the same four helpers, and the hand-rolled login was
subtly wrong: it set :user_token but not :live_socket_id, so LiveView's
disconnect-on-logout never fired and a session-invalidation test was the only
thing that would ever have caught it. That is a worse outcome than
duplication, and it is what a shipped helper fixes.
What is deliberately NOT here
No ConnCase, no DataCase, no Ecto.Adapters.SQL.Sandbox calls. Those are
bound to your endpoint and your repo, and a copy compiled in the kit's
context could not adapt to either. Sandbox ownership stays yours. Everything
here is portable: the fixtures go through Auth.register_user/1, which uses
the configured repo, and the session helpers only put keys into a conn.
Confirmed vs unconfirmed — read the test, do not memorise a default
user_fixture/1 produces an unconfirmed user, honestly mirroring what
register_user/1 does. Confirmation flips authentication behaviour, so a
fixture that silently confirmed would leave a reader of
user = user_fixture()unable to tell why a redirect gate did or did not fire. Ask for
confirmed_user_fixture/1 when you mean confirmed.
(confirmed_at == nil after registration is correct, not a defect being
papered over: registration_changeset/3 refuses to cast it, confirmation is
its own transition, and the gate exists precisely to handle the
registered-but-unconfirmed state — so tests have to be able to produce it.)
Usage
defmodule MyAppWeb.AdminTest do
use MyAppWeb.ConnCase
import PhoenixKit.Test.Fixtures
test "an admin reaches the dashboard", %{conn: conn} do
%{conn: conn} = register_and_log_in_user(%{conn: conn})
assert conn |> get(~p"/phoenix_kit/admin") |> html_response(200)
end
end
Summary
Functions
A confirmed user holding the Admin role.
A registered user whose email is confirmed.
Puts user's session token into conn.
A confirmed user, logged in on the given conn. The 90% case.
A real %Scope{} for user, with roles and permissions loaded.
An email address no other fixture in this run will use.
A registered, unconfirmed user.
A password that satisfies the registration changeset.
Functions
@spec admin_fixture(map()) :: PhoenixKit.Users.Auth.User.t()
A confirmed user holding the Admin role.
@spec confirmed_user_fixture(map()) :: PhoenixKit.Users.Auth.User.t()
A registered user whose email is confirmed.
@spec log_in_user(Plug.Conn.t(), PhoenixKit.Users.Auth.User.t()) :: Plug.Conn.t()
Puts user's session token into conn.
Sets both :user_token and :live_socket_id. The second one is the
reason this helper exists: without it PhoenixKitWeb.Endpoint.broadcast has
no topic to reach the socket on, so logging out never disconnects the
LiveView — and nothing but a session-invalidation test would reveal it.
A confirmed user, logged in on the given conn. The 90% case.
Returns the context map with :user and an updated :conn, so it composes as
an ExUnit setup:
setup :register_and_log_in_user
@spec scope_for(PhoenixKit.Users.Auth.User.t() | nil) :: PhoenixKit.Users.Auth.Scope.t()
A real %Scope{} for user, with roles and permissions loaded.
For testing something that takes a scope directly, without a conn.
@spec unique_user_email() :: String.t()
An email address no other fixture in this run will use.
@spec user_fixture(map()) :: PhoenixKit.Users.Auth.User.t()
A registered, unconfirmed user.
Pass any register_user/1 attributes to override; email and password are
filled in with unique valid values when omitted.
@spec valid_user_password() :: String.t()
A password that satisfies the registration changeset.