Packages
phoenix_ecto
3.0.0-rc.0
4.7.0
4.6.6
4.6.5
4.6.4
4.6.3
4.6.2
4.6.1
4.6.0
4.5.1
4.5.0
4.4.3
4.4.2
4.4.1
4.4.0
4.3.0
4.2.1
4.2.0
4.1.0
4.0.0
3.6.0
3.5.0
retired
3.4.0
3.3.0
3.2.3
3.2.2
3.2.1
3.2.0
3.1.0
3.1.0-rc.0
3.0.1
3.0.0
3.0.0-rc.0
3.0.0-beta.2
3.0.0-beta.1
3.0.0-beta.0
2.0.3
2.0.2
2.0.1
2.0.0
1.2.0
1.1.0
1.0.0
0.9.0
0.8.1
0.8.0
0.7.0
0.6.0
0.5.0
0.4.0
0.3.2
0.3.1
0.3.0
0.2.0
0.1.0
Integration between Phoenix & Ecto
Current section
Files
Jump to
Current section
Files
lib/phoenix_ecto/sql/sandbox.ex
defmodule Phoenix.Ecto.SQL.Sandbox do
@moduledoc """
A plug to allow concurrent, transactional acceptance tests with Ecto.Adapters.SQL.Sandbox.
## 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
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](https://hex.pm/packages/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)
end
"""
import Plug.Conn
def init(opts \\ []) do
Keyword.get(opts, :sandbox, Ecto.Adapters.SQL.Sandbox)
end
def call(conn, sandbox) do
conn
|> get_req_header("user-agent")
|> List.first
|> extract_metadata
|> allow_sandbox_access(sandbox)
conn
end
@doc """
Returns metadata to associate with the session
to allow the endpoint to acces the database connection checked
out by the test process.
"""
@spec metadata_for(Ecto.Repo.t | [Ecto.Repo.t], pid) :: map
def metadata_for(repo_or_repos, pid) when is_pid(pid) do
%{repo: repo_or_repos, owner: pid}
end
defp allow_sandbox_access(%{repo: repo, owner: owner}, sandbox) do
Enum.each(List.wrap(repo), &sandbox.allow(&1, owner, self()))
end
defp allow_sandbox_access(_metadata, _sandbox), do: nil
defp extract_metadata(user_agent) when is_binary(user_agent) do
ua_last_part = user_agent |> String.split("/") |> List.last
case Regex.run(~r/BeamMetadata \((.*?)\)/, ua_last_part) do
[_, metadata] -> parse_metadata(metadata)
_ -> %{}
end
end
defp extract_metadata(_), do: %{}
defp parse_metadata(encoded_metadata) do
encoded_metadata
|> Base.url_decode64!
|> :erlang.binary_to_term
|> case do
{:v1, metadata} -> metadata
_ -> %{}
end
end
end