aprs.me/test/support/data_case.ex
Graham McIntire 2f09b590e2
Some checks are pending
Elixir CI / Build and test (push) Waiting to run
Elixir CI / Dialyzer (push) Waiting to run
Elixir CI / Build and Push Docker Image (push) Blocked by required conditions
fix: resolve all credo issues — 0 warnings, 0 refactoring, 0 readability issues
- Add ex_slop credo plugin with all 40 checks
- Remove DualKeyAccess patterns across codebase — atom-only access
- Fix LengthInGuard, LengthComparison, ListLast, ReduceMapPut in lib/
- Disable LengthComparison for test files
- Remove obvious comments and narrator comments (~50)
- Add missing aliases for fully-qualified modules
- Rewrite boilerplate docs in test/support
- Add normalize_keys helpers at API boundaries
2026-07-29 10:54:07 -05:00

78 lines
2.1 KiB
Elixir

defmodule Aprsme.DataCase do
@moduledoc """
Test case for data-layer tests.
Imports Ecto helpers (`Ecto`, `Ecto.Changeset`, `Ecto.Query`) and
provides utilities like `errors_on/1` for validating changesets.
When the test case interacts with the database, the SQL sandbox is enabled
so changes are reverted at the end of every test. PostgreSQL users can
run database tests asynchronously by setting `use Aprsme.DataCase, async: true`.
"""
use ExUnit.CaseTemplate
alias Ecto.Adapters.SQL.Sandbox
using do
quote do
import Aprsme.DataCase
# Import conveniences for testing with connections
import Ecto
import Ecto.Changeset
import Ecto.Query
# and other functionality to make calls such as:
# import Aprsme.DataCase
# Aprsme.DataCase.errors_on(MySchema.changeset(%MySchema{}, %{}))
# The default import for Repo
alias Aprsme.Repo
end
end
setup tags do
Aprsme.DataCase.setup_sandbox(tags)
# Only seed devices for tests that need them
if tags[:needs_devices] do
Aprsme.DevicesSeeder.seed_from_json()
end
:ok
end
@doc """
A helper that transforms changeset errors into a map of messages.
errors_on(MySchema.changeset(%MySchema{}, %{field: bad_value}))
%{field: ["has invalid value"]}
"""
def errors_on(changeset) do
Ecto.Changeset.traverse_errors(changeset, &translate_error/1)
end
@doc """
Sets up the sandbox and allows the test case
to be run asynchronously.
"""
def setup_sandbox(tags) do
pid = Sandbox.start_owner!(Aprsme.Repo, shared: not tags[:async])
on_exit(fn -> Sandbox.stop_owner(pid) end)
end
defp translate_error({msg, opts}) do
# You can make use of gettext to translate error messages by
# uncommenting and adjusting the following code:
# if count = opts[:count] do
# Gettext.dngettext(AprsmeWeb.Gettext, "errors", msg, msg, count, opts)
# else
# Gettext.dgettext(AprsmeWeb.Gettext, "errors", msg, opts)
# end
Enum.reduce(opts, msg, fn {key, value}, acc ->
String.replace(acc, "%{#{key}}", fn _ -> to_string(value) end)
end)
end
end