diff options
Diffstat (limited to '')
-rw-r--r-- | test/support/channel_case.ex | 43 | ||||
-rw-r--r-- | test/support/conn_case.ex | 44 | ||||
-rw-r--r-- | test/support/model_case.ex | 65 |
3 files changed, 152 insertions, 0 deletions
diff --git a/test/support/channel_case.ex b/test/support/channel_case.ex new file mode 100644 index 0000000..f121634 --- /dev/null +++ b/test/support/channel_case.ex @@ -0,0 +1,43 @@ +defmodule TheTranscriberBackend.ChannelCase do + @moduledoc """ + This module defines the test case to be used by + channel tests. + + Such tests rely on `Phoenix.ChannelTest` and also + import other functionality to make it easier + to build and query models. + + Finally, if the test case interacts with the database, + it cannot be async. For this reason, every test runs + inside a transaction which is reset at the beginning + of the test unless the test case is marked as async. + """ + + use ExUnit.CaseTemplate + + using do + quote do + # Import conveniences for testing with channels + use Phoenix.ChannelTest + + alias TheTranscriberBackend.Repo + import Ecto + import Ecto.Changeset + import Ecto.Query + + + # The default endpoint for testing + @endpoint TheTranscriberBackend.Endpoint + end + end + + setup tags do + :ok = Ecto.Adapters.SQL.Sandbox.checkout(TheTranscriberBackend.Repo) + + unless tags[:async] do + Ecto.Adapters.SQL.Sandbox.mode(TheTranscriberBackend.Repo, {:shared, self()}) + end + + :ok + end +end diff --git a/test/support/conn_case.ex b/test/support/conn_case.ex new file mode 100644 index 0000000..6f0e522 --- /dev/null +++ b/test/support/conn_case.ex @@ -0,0 +1,44 @@ +defmodule TheTranscriberBackend.ConnCase do + @moduledoc """ + This module defines the test case to be used by + tests that require setting up a connection. + + Such tests rely on `Phoenix.ConnTest` and also + import other functionality to make it easier + to build and query models. + + Finally, if the test case interacts with the database, + it cannot be async. For this reason, every test runs + inside a transaction which is reset at the beginning + of the test unless the test case is marked as async. + """ + + use ExUnit.CaseTemplate + + using do + quote do + # Import conveniences for testing with connections + use Phoenix.ConnTest + + alias TheTranscriberBackend.Repo + import Ecto + import Ecto.Changeset + import Ecto.Query + + import TheTranscriberBackend.Router.Helpers + + # The default endpoint for testing + @endpoint TheTranscriberBackend.Endpoint + end + end + + setup tags do + :ok = Ecto.Adapters.SQL.Sandbox.checkout(TheTranscriberBackend.Repo) + + unless tags[:async] do + Ecto.Adapters.SQL.Sandbox.mode(TheTranscriberBackend.Repo, {:shared, self()}) + end + + {:ok, conn: Phoenix.ConnTest.build_conn()} + end +end diff --git a/test/support/model_case.ex b/test/support/model_case.ex new file mode 100644 index 0000000..9f16428 --- /dev/null +++ b/test/support/model_case.ex @@ -0,0 +1,65 @@ +defmodule TheTranscriberBackend.ModelCase do + @moduledoc """ + This module defines the test case to be used by + model tests. + + You may define functions here to be used as helpers in + your model tests. See `errors_on/2`'s definition as reference. + + Finally, if the test case interacts with the database, + it cannot be async. For this reason, every test runs + inside a transaction which is reset at the beginning + of the test unless the test case is marked as async. + """ + + use ExUnit.CaseTemplate + + using do + quote do + alias TheTranscriberBackend.Repo + + import Ecto + import Ecto.Changeset + import Ecto.Query + import TheTranscriberBackend.ModelCase + end + end + + setup tags do + :ok = Ecto.Adapters.SQL.Sandbox.checkout(TheTranscriberBackend.Repo) + + unless tags[:async] do + Ecto.Adapters.SQL.Sandbox.mode(TheTranscriberBackend.Repo, {:shared, self()}) + end + + :ok + end + + @doc """ + Helper for returning list of errors in a struct when given certain data. + + ## Examples + + Given a User schema that lists `:name` as a required field and validates + `:password` to be safe, it would return: + + iex> errors_on(%User{}, %{password: "password"}) + [password: "is unsafe", name: "is blank"] + + You could then write your assertion like: + + assert {:password, "is unsafe"} in errors_on(%User{}, %{password: "password"}) + + You can also create the changeset manually and retrieve the errors + field directly: + + iex> changeset = User.changeset(%User{}, password: "password") + iex> {:password, "is unsafe"} in changeset.errors + true + """ + def errors_on(struct, data) do + struct.__struct__.changeset(struct, data) + |> Ecto.Changeset.traverse_errors(&TheTranscriberBackend.ErrorHelpers.translate_error/1) + |> Enum.flat_map(fn {key, errors} -> for msg <- errors, do: {key, msg} end) + end +end |