Working test version of confirmation email delivery

This commit is contained in:
2025-03-16 20:22:48 +02:00
parent d21b92045e
commit a454bb2c49
12 changed files with 82 additions and 20 deletions

3
.gitignore vendored
View File

@@ -40,3 +40,6 @@ run.sh
# Prod db variable script
prod_db_vars
# DKIM private key
/priv/keys/dkim_private.pem

View File

@@ -68,12 +68,24 @@ if config_env() == :prod do
# In production you need to configure the mailer to use a different adapter.
# Also, you may need to configure the Swoosh API client of your choice if you
# are not using SMTP. Here is an example of the configuration:
#
# config :osuuspuutarha, Osuuspuutarha.Mailer,
# adapter: Swoosh.Adapters.Mailgun,
# api_key: System.get_env("MAILGUN_API_KEY"),
# domain: System.get_env("MAILGUN_DOMAIN")
#
config :osuuspuutarha, Osuuspuutarha.Mailer,
adapter: Swoosh.Adapters.SMTP,
relay: "mail.tietokonepaja.fi",
username: System.get_env("SMTP_USERNAME"),
password: System.get_env("SMTP_PASSWORD"),
ssl: false,
tls: :never,
auth: :never,
port: 25,
dkim: [
s: "email",
d: "livonsaarenosuuspuutarha.fi",
private_key: {:pem_plain, File.read!("priv/keys/domain.private")}
],
retries: 2,
no_mx_lookups: false
# For this example you need include a HTTP client required by Swoosh API client.
# Swoosh supports Hackney and Finch out of the box:
#

View File

@@ -0,0 +1,15 @@
defmodule Osuuspuutarha.ConfirmationSender do
@moduledoc """
This module is responsible for sending confirmation emails.
"""
import Swoosh.Email
def send_confirmation_email(order) do
new()
|> to({"Testi Testinen", "livonsaaren.tietokonepaja@gmail.com"})
|> from({"Livonsaaren Osuuspuutarha", "noreply@livonsaarenosuuspuutarha.fi"})
|> subject("Kiitokset tilauksesta!")
|> html_body("<h1>Hello #{order.fname}</h1>")
|> text_body("Hello #{order.fname}\n")
end
end

View File

@@ -8,6 +8,9 @@ defmodule Osuuspuutarha.Orders do
alias Osuuspuutarha.Orders.Order
alias Osuuspuutarha.ConfirmationSender
alias Osuuspuutarha.Mailer
@doc """
Returns the list of orders.
@@ -42,19 +45,34 @@ defmodule Osuuspuutarha.Orders do
## Examples
iex> create_order(%{field: value})
iex> process_order(%{field: value})
{:ok, %Order{}}
iex> create_order(%{field: bad_value})
iex> process_order(%{field: bad_value})
{:error, %Ecto.Changeset{}}
"""
def create_order(attrs \\ %{}) do
def process_order(attrs \\ %{}) do
case insert_order(attrs) do
{:ok, order} ->
send_confirmation_email_and_deliver(order)
{:error, changeset} ->
{:error, changeset}
end
end
defp insert_order(attrs) do
%Order{}
|> Order.changeset(attrs)
|> Repo.insert()
end
defp send_confirmation_email_and_deliver(order) do
ConfirmationSender.send_confirmation_email(order)
|> Mailer.deliver()
end
@doc """
Updates a order.

View File

@@ -41,7 +41,7 @@ defmodule OsuuspuutarhaWeb.OrderLive.FormComponent do
end
defp save_order(socket, :new, order_params) do
case Orders.create_order(order_params) do
case Orders.process_order(order_params) do
{:ok, _order} ->
{:noreply,
socket

View File

@@ -0,0 +1,3 @@
<div>
<h1>Osuuspuutarhan testimaili, <%= @variable %>!</h1>
</div>

View File

@@ -0,0 +1,8 @@
<html>
<head>
<title><%= @email.subject %></title>
</head>
<body>
<%= @inner_content %>
</body>
</html>

View File

@@ -42,14 +42,15 @@ defmodule Osuuspuutarha.MixProject do
{:floki, ">= 0.30.0", only: :test},
{:phoenix_live_dashboard, "~> 0.6"},
{:esbuild, "~> 0.4", runtime: Mix.env() == :dev},
{:swoosh, "~> 1.3"},
{:swoosh, "~> 1.6"},
{:telemetry_metrics, "~> 0.6"},
{:telemetry_poller, "~> 1.0"},
{:gettext, "~> 0.18"},
{:jason, "~> 1.2"},
{:plug_cowboy, "~> 2.5"},
{:elixlsx, "~> 0.5.1"},
{:credo, "~> 1.7", only: [:dev, :test], runtime: false}
{:credo, "~> 1.7", only: [:dev, :test], runtime: false},
{:gen_smtp, "~> 1.0"}
]
end

View File

@@ -15,6 +15,7 @@
"expo": {:hex, :expo, "0.4.0", "bbe4bf455e2eb2ebd2f1e7d83530ce50fb9990eb88fc47855c515bfdf1c6626f", [:mix], [], "hexpm", "a8ed1683ec8b7c7fa53fd7a41b2c6935f539168a6bb0616d7fd6b58a36f3abf2"},
"file_system": {:hex, :file_system, "0.2.10", "fb082005a9cd1711c05b5248710f8826b02d7d1784e7c3451f9c1231d4fc162d", [:mix], [], "hexpm", "41195edbfb562a593726eda3b3e8b103a309b733ad25f3d642ba49696bf715dc"},
"floki": {:hex, :floki, "0.34.2", "5fad07ef153b3b8ec110b6b155ec3780c4b2c4906297d0b4be1a7162d04a7e02", [:mix], [], "hexpm", "26b9d50f0f01796bc6be611ca815c5e0de034d2128e39cc9702eee6b66a4d1c8"},
"gen_smtp": {:hex, :gen_smtp, "1.2.0", "9cfc75c72a8821588b9b9fe947ae5ab2aed95a052b81237e0928633a13276fd3", [:rebar3], [{:ranch, ">= 1.8.0", [hex: :ranch, repo: "hexpm", optional: false]}], "hexpm", "5ee0375680bca8f20c4d85f58c2894441443a743355430ff33a783fe03296779"},
"gettext": {:hex, :gettext, "0.22.1", "e7942988383c3d9eed4bdc22fc63e712b655ae94a672a27e4900e3d4a2c43581", [:mix], [{:expo, "~> 0.4.0", [hex: :expo, repo: "hexpm", optional: false]}], "hexpm", "ad105b8dab668ee3f90c0d3d94ba75e9aead27a62495c101d94f2657a190ac5d"},
"jason": {:hex, :jason, "1.4.4", "b9226785a9aa77b6857ca22832cffa5d5011a667207eb2a0ad56adb5db443b8a", [:mix], [{:decimal, "~> 1.0 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: true]}], "hexpm", "c5eb0cab91f094599f94d55bc63409236a8ec69a21a67814529e8d5f6cc90b3b"},
"mime": {:hex, :mime, "2.0.6", "8f18486773d9b15f95f4f4f1e39b710045fa1de891fada4516559967276e4dc2", [:mix], [], "hexpm", "c9945363a6b26d747389aac3643f8e0e09d30499a138ad64fe8fd1d13d9b153e"},
@@ -25,6 +26,7 @@
"phoenix_live_reload": {:hex, :phoenix_live_reload, "1.4.1", "2aff698f5e47369decde4357ba91fc9c37c6487a512b41732818f2204a8ef1d3", [:mix], [{:file_system, "~> 0.2.1 or ~> 0.3", [hex: :file_system, repo: "hexpm", optional: false]}, {:phoenix, "~> 1.4", [hex: :phoenix, repo: "hexpm", optional: false]}], "hexpm", "9bffb834e7ddf08467fe54ae58b5785507aaba6255568ae22b4d46e2bb3615ab"},
"phoenix_live_view": {:hex, :phoenix_live_view, "0.17.14", "5ec615d4d61bf9d4755f158bd6c80372b715533fe6d6219e12d74fb5eedbeac1", [:mix], [{:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:phoenix, "~> 1.6.0 or ~> 1.7.0", [hex: :phoenix, repo: "hexpm", optional: false]}, {:phoenix_html, "~> 3.1", [hex: :phoenix_html, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4.2 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "afeb6ba43ce329a6f7fc1c9acdfc6d3039995345f025febb7f409a92f6faebd3"},
"phoenix_pubsub": {:hex, :phoenix_pubsub, "2.1.3", "3168d78ba41835aecad272d5e8cd51aa87a7ac9eb836eabc42f6e57538e3731d", [:mix], [], "hexpm", "bba06bc1dcfd8cb086759f0edc94a8ba2bc8896d5331a1e2c2902bf8e36ee502"},
"phoenix_swoosh": {:hex, :phoenix_swoosh, "1.2.1", "b74ccaa8046fbc388a62134360ee7d9742d5a8ae74063f34eb050279de7a99e1", [:mix], [{:finch, "~> 0.8", [hex: :finch, repo: "hexpm", optional: true]}, {:hackney, "~> 1.10", [hex: :hackney, repo: "hexpm", optional: true]}, {:phoenix, "~> 1.6", [hex: :phoenix, repo: "hexpm", optional: true]}, {:phoenix_html, "~> 3.0 or ~> 4.0", [hex: :phoenix_html, repo: "hexpm", optional: true]}, {:phoenix_view, "~> 1.0 or ~> 2.0", [hex: :phoenix_view, repo: "hexpm", optional: false]}, {:swoosh, "~> 1.5", [hex: :swoosh, repo: "hexpm", optional: false]}], "hexpm", "4000eeba3f9d7d1a6bf56d2bd56733d5cadf41a7f0d8ffe5bb67e7d667e204a2"},
"phoenix_template": {:hex, :phoenix_template, "1.0.4", "e2092c132f3b5e5b2d49c96695342eb36d0ed514c5b252a77048d5969330d639", [:mix], [{:phoenix_html, "~> 2.14.2 or ~> 3.0 or ~> 4.0", [hex: :phoenix_html, repo: "hexpm", optional: true]}], "hexpm", "2c0c81f0e5c6753faf5cca2f229c9709919aba34fab866d3bc05060c9c444206"},
"phoenix_view": {:hex, :phoenix_view, "2.0.4", "b45c9d9cf15b3a1af5fb555c674b525391b6a1fe975f040fb4d913397b31abf4", [:mix], [{:phoenix_html, "~> 2.14.2 or ~> 3.0 or ~> 4.0", [hex: :phoenix_html, repo: "hexpm", optional: true]}, {:phoenix_template, "~> 1.0", [hex: :phoenix_template, repo: "hexpm", optional: false]}], "hexpm", "4e992022ce14f31fe57335db27a28154afcc94e9983266835bb3040243eb620b"},
"plug": {:hex, :plug, "1.16.1", "40c74619c12f82736d2214557dedec2e9762029b2438d6d175c5074c933edc9d", [:mix], [{:mime, "~> 1.0 or ~> 2.0", [hex: :mime, repo: "hexpm", optional: false]}, {:plug_crypto, "~> 1.1.1 or ~> 1.2 or ~> 2.0", [hex: :plug_crypto, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4.3 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "a13ff6b9006b03d7e33874945b2755253841b238c34071ed85b0e86057f8cddc"},

View File

@@ -34,7 +34,7 @@ defmodule Osuuspuutarha.OrdersTest do
assert Orders.get_order!(order.id) == order
end
test "create_order/1 with valid data creates a order" do
test "process_order/1 with valid data creates a order" do
valid_attrs = %{
address: "some address",
city: "some city",
@@ -51,7 +51,7 @@ defmodule Osuuspuutarha.OrdersTest do
early_bird: true
}
assert {:ok, %Order{} = order} = Orders.create_order(valid_attrs)
assert {:ok, %Order{} = order} = Orders.process_order(valid_attrs)
assert order.address == "some address"
assert order.city == "some city"
assert order.email == "some email"
@@ -67,8 +67,8 @@ defmodule Osuuspuutarha.OrdersTest do
assert order.early_bird == true
end
test "create_order/1 with invalid data returns error changeset" do
assert {:error, %Ecto.Changeset{}} = Orders.create_order(@invalid_attrs)
test "process_order/1 with invalid data returns error changeset" do
assert {:error, %Ecto.Changeset{}} = Orders.process_order(@invalid_attrs)
end
test "update_order/2 with valid data updates the order" do

View File

@@ -50,13 +50,13 @@ defmodule OsuuspuutarhaWeb.OrderLiveTest do
early_bird: false
}
defp create_order(_) do
defp process_order(_) do
order = order_fixture()
%{order: order}
end
describe "Index" do
setup [:create_order]
setup [:process_order]
test "lists all orders", %{conn: conn, order: order} do
{:ok, _index_live, html} = live(conn, Routes.order_index_path(conn, :index))
@@ -118,7 +118,7 @@ defmodule OsuuspuutarhaWeb.OrderLiveTest do
end
describe "Show" do
setup [:create_order]
setup [:process_order]
test "displays order", %{conn: conn, order: order} do
{:ok, _show_live, html} = live(conn, Routes.order_show_path(conn, :show, order))

View File

@@ -25,7 +25,7 @@ defmodule Osuuspuutarha.OrdersFixtures do
split_invoice: true,
early_bird: true
})
|> Osuuspuutarha.Orders.create_order()
|> Osuuspuutarha.Orders.process_order()
order
end