prop/test/support/conn_case.ex
Graham McIntire 82bcaa5a54
Some checks failed
Build and Push / Build and Push Docker Image (push) Has been cancelled
refactor: idiomatic test sandbox setup (manual mode, single reset hook)
Replace the non-idiomatic :auto sandbox mode with :manual, eliminating
the root cause of stale data across test runs. The :auto mode let any
process auto-checkout and commit outside test transactions — Oban in
testing:inline already disables plugins/queues, so :auto was never
needed.

Changes:
- test_helper: Sandbox.mode(Repo, :manual); drop manual app boot (mix
  now starts the app idiomatically), drop --no-start alias, drop
  table-cleanup loop
- DataCase: single reset_test_state/0 consolidates GridCache.clear,
  ScoreCache.clear, score-file wipe, and default HTTP stubs; drop
  the :auto-restore on_exit hack; setup_sandbox now just start_owner
- ConnCase: delegates shared reset to DataCase, removes duplicate
  cache clears and stub installs
- config: pool Ecto.Adapters.SQL.Sandbox (idiomatic canonical form)

Note: GridCache/ScoreCache are globally-registered GenServers, so
the architecturally clean per-test start_supervised! approach
conflicts with async:true (parallel tests can't register the same
name). The centralized clear in reset_test_state is the practical
compromise — one place, documented, single call.
2026-08-04 17:47:49 -05:00

61 lines
1.8 KiB
Elixir

defmodule MicrowavepropWeb.ConnCase do
@moduledoc """
Test case template for HTTP connection tests.
"""
use ExUnit.CaseTemplate
alias Microwaveprop.Accounts
alias Microwaveprop.Accounts.Scope
alias Microwaveprop.Accounts.User
alias Microwaveprop.AccountsFixtures
alias Microwaveprop.DataCase
alias Phoenix.Ecto.SQL.Sandbox
using do
quote do
use MicrowavepropWeb, :verified_routes
import MicrowavepropWeb.ConnCase
import Phoenix.ConnTest
import Plug.Conn
@endpoint MicrowavepropWeb.Endpoint
end
end
setup tags do
owner = DataCase.setup_sandbox(tags)
DataCase.reset_test_state()
metadata = Sandbox.metadata_for(Microwaveprop.Repo, owner)
conn = Plug.Conn.put_req_header(Phoenix.ConnTest.build_conn(), "user-agent", Sandbox.encode_metadata(metadata))
{:ok, conn: conn}
end
@spec register_and_log_in_user(map()) :: %{conn: Plug.Conn.t(), user: User.t(), scope: Scope.t()}
def register_and_log_in_user(%{conn: conn} = context) do
user = AccountsFixtures.user_fixture()
scope = Scope.for_user(user)
opts = context |> Map.take([:token_authenticated_at]) |> Enum.to_list()
%{conn: log_in_user(conn, user, opts), user: user, scope: scope}
end
@spec log_in_user(Plug.Conn.t(), User.t(), Keyword.t()) :: Plug.Conn.t()
def log_in_user(conn, user, opts \\ []) do
token = Accounts.generate_user_session_token(user)
maybe_set_token_authenticated_at(token, opts[:token_authenticated_at])
conn
|> Phoenix.ConnTest.init_test_session(%{})
|> Plug.Conn.put_session(:user_token, token)
end
defp maybe_set_token_authenticated_at(_token, nil), do: nil
defp maybe_set_token_authenticated_at(token, authenticated_at) do
AccountsFixtures.override_token_authenticated_at(token, authenticated_at)
end
end