Current section
Files
Jump to
Current section
Files
lib/sandbox_shim.ex
defmodule SandboxShim do
@moduledoc """
Compile-time macros for wiring test sandbox infrastructure into
Phoenix endpoints and LiveViews. Emits nothing outside test env.
# endpoint.ex
import SandboxShim
sandbox_plugs()
sandbox_socket "/live", Phoenix.LiveView.Socket,
websocket: [connect_info: [session: @session_options]]
# your_app_web.ex
def live_view do
quote do
use Phoenix.LiveView
import SandboxShim
sandbox_on_mount()
end
end
Zero runtime overhead. No production dependencies on test libraries.
"""
@doc """
Emits `plug(mod)` for every plug declared by configured sandbox adapters.
Emits nothing outside test env.
"""
defmacro sandbox_plugs do
if test_env?() and ensure_sandbox_loaded?() do
for mod <- SandboxCase.Sandbox.collect_plugs() do
quote do: plug(unquote(mod))
end
end
end
@doc """
Emits `on_mount(mod)` for every hook declared by configured sandbox adapters.
Emits nothing outside test env.
"""
defmacro sandbox_on_mount do
if test_env?() and ensure_sandbox_loaded?() do
for mod <- SandboxCase.Sandbox.collect_hooks() do
quote do: on_mount(unquote(mod))
end
end
end
@doc """
Declares a Phoenix LiveView socket, injecting `:user_agent` into
`connect_info` in test env. In production, emits a plain `socket/3`.
"""
defmacro sandbox_socket(path, module, opts) do
if test_env?() do
opts = inject_user_agent(opts)
quote do: socket(unquote(path), unquote(module), unquote(opts))
else
quote do: socket(unquote(path), unquote(module), unquote(opts))
end
end
defp inject_user_agent(opts) do
Keyword.update(opts, :websocket, [connect_info: [:user_agent]], fn ws_opts ->
Keyword.update(ws_opts, :connect_info, [:user_agent], fn ci ->
if :user_agent in ci, do: ci, else: [:user_agent | ci]
end)
end)
end
defp ensure_sandbox_loaded? do
Code.ensure_loaded?(SandboxCase.Sandbox)
end
@doc false
def test_env? do
function_exported?(Mix, :env, 0) and Mix.env() == :test
end
end