Phoenix/Ecto v4.1.0 Phoenix.Ecto.SQL.Sandbox View Source

A plug to allow concurrent, transactional acceptance tests with [Ecto.Adapters.SQL.Sandbox] (https://hexdocs.pm/ecto_sql/Ecto.Adapters.SQL.Sandbox.html).

Example

This plug should only be used during tests. First, set a flag to enable it in config/test.exs:

config :your_app, sql_sandbox: true

And use the flag to conditionally add the plug to lib/your_app/endpoint.ex:

if Application.get_env(:your_app, :sql_sandbox) do
  plug Phoenix.Ecto.SQL.Sandbox
end

It's important that this is at the top of endpoint.ex, before any other plugs.

Then, within an acceptance test, checkout a sandboxed connection as before. Use metadata_for/2 helper to get the session metadata to that will allow access to the test's connection. Here's an example using Hound:

use Hound.Helpers

setup do
  :ok = Ecto.Adapters.SQL.Sandbox.checkout(YourApp.Repo)
  metadata = Phoenix.Ecto.SQL.Sandbox.metadata_for(YourApp.Repo, self())
  Hound.start_session(metadata: metadata)
  :ok
end

Concurrent end-to-end tests with external clients

Concurrent and transactional tests for external HTTP clients is supported, allowing for complete end-to-end tests. This is useful for cases such as JavaScript test suites for single page applications that exercise the Phoenix endpoint for end-to-end test setup and teardown. To enable this, you can expose a sandbox route on the Phoenix.Ecto.SQL.Sandbox plug by providing the :at, and :repo options. For example:

plug Phoenix.Ecto.SQL.Sandbox,
  at: "/sandbox",
  repo: MyApp.Repo,
  timeout: 15_000 # the default

This would expose a route at "/sandbox" for the given repo where external clients send POST requests to spawn a new sandbox session, and DELETE requests to stop an active sandbox session. By default, the external client is expected to pass up the "user-agent" header containing serialized sandbox metadata returned from the POST request, but this value may customized with the :header option.

Link to this section Summary

Functions

Decodes encoded metadata back into map generated from metadata_for/2.

Encodes metadata generated by metadata_for/2 for client response.

Returns metadata to associate with the session to allow the endpoint to access the database connection checked out by the test process.

Spawns a sandbox session to checkout a connection for a remote client.

Stops a sandbox session holding a connection for a remote client.

Link to this section Functions

Link to this function

decode_metadata(encoded_meta)

View Source

Decodes encoded metadata back into map generated from metadata_for/2.

Link to this function

encode_metadata(metadata)

View Source

Encodes metadata generated by metadata_for/2 for client response.

Link to this function

metadata_for(repo_or_repos, pid)

View Source
metadata_for(Ecto.Repo.t() | [Ecto.Repo.t()], pid()) :: map()

Returns metadata to associate with the session to allow the endpoint to access the database connection checked out by the test process.

Link to this function

start_child(repo, opts \\ [])

View Source

Spawns a sandbox session to checkout a connection for a remote client.

Examples

iex> {:ok, _owner_pid, metadata} = start_child(MyApp.Repo)

Stops a sandbox session holding a connection for a remote client.

Examples

iex> {:ok, owner_pid, metadata} = start_child(MyApp.Repo)
iex> :ok = stop(owner_pid)