58 lines
1.6 kB
1
defmodule Blog.DataCase do
2
@moduledoc """
3
This module defines the setup for tests requiring
4
access to the application's data layer.
5
6
You may define functions here to be used as helpers in
7
your tests.
8
9
Finally, if the test case interacts with the database,
10
we enable the SQL sandbox, so changes done to the database
11
are reverted at the end of every test. If you are using
12
PostgreSQL, you can even run database tests asynchronously
13
by setting `use Blog.DataCase, async: true`, although
14
this option is not recommended for other databases.
15
"""
16
17
use ExUnit.CaseTemplate
18
19
using do
20
quote do
21
alias Blog.Repo
22
23
import Ecto
24
import Ecto.Changeset
25
import Ecto.Query
26
import Blog.DataCase
27
end
28
end
29
30
setup tags do
31
Blog.DataCase.setup_sandbox(tags)
32
:ok
33
end
34
35
@doc """
36
Sets up the sandbox based on the test tags.
37
"""
38
def setup_sandbox(tags) do
39
pid = Ecto.Adapters.SQL.Sandbox.start_owner!(Blog.Repo, shared: not tags[:async])
40
on_exit(fn -> Ecto.Adapters.SQL.Sandbox.stop_owner(pid) end)
41
end
42
43
@doc """
44
A helper that transforms changeset errors into a map of messages.
45
46
assert {:error, changeset} = Accounts.create_user(%{password: "short"})
47
assert "password is too short" in errors_on(changeset).password
48
assert %{password: ["password is too short"]} = errors_on(changeset)
49
50
"""
51
def errors_on(changeset) do
52
Ecto.Changeset.traverse_errors(changeset, fn {message, opts} ->
53
Regex.replace(~r"%{(\w+)}", message, fn _, key ->
54
opts |> Keyword.get(String.to_existing_atom(key), key) |> to_string()
55
end)
56
end)
57
end
58
end
59