Mutare mutators for the
phoenix_swoosh template-rendering surface — the layer
Phoenix.Swoosh adds on top of a Swoosh mailer.
This package depends on mutare_swoosh, so the base email-construction/delivery families are
on your code path too; compose the two presets for a full mailer surface (see "Usage").
Families
Mutare.Phoenix.Swoosh.RenderBody—:render_body: remove arender_body/2,3call (the email ships with no rendered body), narrow an atom template to one of its two string forms (only the.html/ only the.textbody renders), or drop one entry from a literalput_new_formats/2map (that extension stops rendering).Mutare.Phoenix.Swoosh.Layout—:mail_layout: remove aput_layout/2/put_new_layout/2call (the body renders in the previous/no layout), or suppress the layout at the render site by setting thelayout:assign tofalse(the body renders bare wherever the layout was configured).
Both families also pin phoenix_swoosh's structural argument positions — the template name,
the layout tuple, the put_new_formats/2 map — so core's value families never mint the
missing-template crash mutants those positions would otherwise get.
Usage
Splice all/0 into :mutators alongside the :builtins group token and the mutare_swoosh
preset, and list this module under :extensions (see below for why):
# .mutare.exs — a phoenix_swoosh mailer app
[
mutators:
[:builtins] ++
Mutare.Swoosh.all(mailer: MyApp.Mailer) ++
Mutare.Phoenix.Swoosh.all(),
extensions: [Mutare.Phoenix.Swoosh]
]all/0 returns only this package's two families — it does not include the base
mutare_swoosh families, so compose Mutare.Swoosh.all/1 explicitly as shown above.
Why the :extensions entry
use Phoenix.Swoosh does not surface render_body the way most uses surface their API.
Its __using__ injects import Phoenix.Swoosh, except: [render_body: 3] plus a local
def render_body(email, template, assigns \\ %{}) that wraps the module function — so the
bare render_body calls a mailer module writes resolve to a hidden local definition, not to
an import. Mutare's in-process use expansion harvests the injected imports faithfully, and
faithfully finds render_body excluded from them: the bare calls stay unresolved, and the
:render_body family only sees qualified/aliased call forms.
This module is therefore also a Mutare.UseExpansion extension. It takes over
use Phoenix.Swoosh and surfaces import Swoosh.Email plus a whole
import Phoenix.Swoosh — deliberately without the except: — standing in for the injected
local wrapper, which forwards to Phoenix.Swoosh.render_body/3 anyway. With it listed under
:extensions, bare render_body calls (both arities, the wrapper's default-argument form
included) resolve, mutate, and get their template position pinned. For the standalone
template style (use Phoenix.Swoosh, template_root: ... — which also does
use Phoenix.View in the caller) it additionally surfaces the import Phoenix.View that
nested use would inject.
It also reads one fact out of the use line: whether the mailer configured a layout
(layout: {MyApp.LayoutView, :email}). That option is compile-time configuration no mutant
can be delivered into, but whether a layout is in effect decides whether suppressing one at
the render site is a real mutant or an equivalent one — so the expansion reports it to
Mutare.Phoenix.Swoosh.Layout as the Mutare.Phoenix.Swoosh.LayoutConfigured marker, the
one channel a use expansion has into a mutator's context.
Without the :extensions entry the families still work on qualified and aliased calls, and
:mail_layout works on bare setter calls too (put_layout/put_new_layout really are
imported) — but bare render_body sites are neither mutated nor pinned, and :mail_layout's
off mutant fires only where the author wrote the layout: assign themselves.
Summary
Functions
@spec all() :: [module(), ...]
This package's two phoenix_swoosh mutator families — RenderBody, Layout.
It does not include the base mutare_swoosh families; compose those explicitly with
Mutare.Swoosh.all/1 when you want the full Swoosh + template surface (see the moduledoc's
"Usage").
iex> Mutare.Phoenix.Swoosh.all()
[Mutare.Phoenix.Swoosh.RenderBody, Mutare.Phoenix.Swoosh.Layout]