From 2bf71e882f63bf3bb83f6e8bf096d928f34a83bc Mon Sep 17 00:00:00 2001 From: Dan Barber Date: Wed, 15 Aug 2018 14:30:52 -0400 Subject: [PATCH] Send email to opponent when new game is created --- config/dev.exs | 4 +++- config/test.exs | 3 +++ lib/chess/emails.ex | 17 ++++++++++++++ lib/chess/mailer.ex | 3 +++ lib/chess_web/controllers/game_controller.ex | 9 ++++++++ lib/chess_web/formatters/user_formatter.ex | 5 +++++ lib/chess_web/router.ex | 4 ++++ .../controllers/game_controller_test.exs | 22 ++++++++++++++++--- 8 files changed, 63 insertions(+), 4 deletions(-) create mode 100644 lib/chess/emails.ex create mode 100644 lib/chess/mailer.ex create mode 100644 lib/chess_web/formatters/user_formatter.ex diff --git a/config/dev.exs b/config/dev.exs index ae84da3..b713c5c 100644 --- a/config/dev.exs +++ b/config/dev.exs @@ -33,7 +33,9 @@ config :logger, :console, format: "[$level] $message\n" # in production as building large stacktraces may be expensive. config :phoenix, :stacktrace_depth, 20 -# Configure your database +config :chess, Chess.Mailer, + adapter: Bamboo.LocalAdapter + config :chess, Chess.Repo, adapter: Ecto.Adapters.Postgres, database: "chess_dev", diff --git a/config/test.exs b/config/test.exs index fc1d4d5..57bde4e 100644 --- a/config/test.exs +++ b/config/test.exs @@ -11,6 +11,9 @@ config :chess, :sql_sandbox, true # Print only warnings and errors during test config :logger, level: :warn +config :chess, Chess.Mailer, + adapter: Bamboo.TestAdapter + # Configure your database config :chess, Chess.Repo, adapter: Ecto.Adapters.Postgres, diff --git a/lib/chess/emails.ex b/lib/chess/emails.ex new file mode 100644 index 0000000..372eb62 --- /dev/null +++ b/lib/chess/emails.ex @@ -0,0 +1,17 @@ +defmodule Chess.Emails do + @moduledoc false + + import Bamboo.Email + + def new_game_email(conn, game) do + new_email() + |> to(game.opponent) + |> from("games@64squares.club") + |> subject("New chess game created!") + |> text_body(""" + #{game.user.name} has invited you to play a game of chess. + + #{ChessWeb.Router.Helpers.game_url(conn, :show, game)} + """) + end +end diff --git a/lib/chess/mailer.ex b/lib/chess/mailer.ex new file mode 100644 index 0000000..ad7f21b --- /dev/null +++ b/lib/chess/mailer.ex @@ -0,0 +1,3 @@ +defmodule Chess.Mailer do + use Bamboo.Mailer, otp_app: :chess +end diff --git a/lib/chess_web/controllers/game_controller.ex b/lib/chess_web/controllers/game_controller.ex index ab46ea6..ff50a82 100644 --- a/lib/chess_web/controllers/game_controller.ex +++ b/lib/chess_web/controllers/game_controller.ex @@ -3,6 +3,7 @@ defmodule ChessWeb.GameController do alias Chess.Store.Game alias Chess.Store.User + alias Chess.Mailer import Chess.Auth, only: [current_user: 1] @@ -40,6 +41,14 @@ defmodule ChessWeb.GameController do |> Repo.insert() |> case do {:ok, game} -> + conn + |> Chess.Emails.new_game_email( + game + |> Repo.preload(:user) + |> Repo.preload(:opponent) + ) + |> Mailer.deliver_later + conn |> put_flash(:info, "Game created successfully.") |> redirect(to: game_path(conn, :show, game)) diff --git a/lib/chess_web/formatters/user_formatter.ex b/lib/chess_web/formatters/user_formatter.ex new file mode 100644 index 0000000..c2da666 --- /dev/null +++ b/lib/chess_web/formatters/user_formatter.ex @@ -0,0 +1,5 @@ +defimpl Bamboo.Formatter, for: Chess.Store.User do + def format_email_address(user, _opts) do + {user.name, user.email} + end +end diff --git a/lib/chess_web/router.ex b/lib/chess_web/router.ex index 7f13675..ee19e94 100644 --- a/lib/chess_web/router.ex +++ b/lib/chess_web/router.ex @@ -53,6 +53,10 @@ defmodule ChessWeb.Router do resources "/games", ChessWeb.Api.GameController, only: [:show, :update] end + if Mix.env == :dev do + forward "/sent_emails", Bamboo.SentEmailViewerPlug + end + defp put_user_token(conn, _) do if current_user = Guardian.Plug.current_resource(conn) do token = Token.sign(conn, "game socket", current_user.id) diff --git a/test/chess_web/controllers/game_controller_test.exs b/test/chess_web/controllers/game_controller_test.exs index 2a32f30..aae03ac 100644 --- a/test/chess_web/controllers/game_controller_test.exs +++ b/test/chess_web/controllers/game_controller_test.exs @@ -1,12 +1,13 @@ defmodule ChessWeb.GameControllerTest do use ChessWeb.ConnCase + use Bamboo.Test alias Chess.Store.Game alias Chess.Auth.Guardian import Chess.Factory - test "lists all entries on index", %{conn: conn} do + test "lists all games on index", %{conn: conn} do user = insert(:user) conn = @@ -17,7 +18,7 @@ defmodule ChessWeb.GameControllerTest do assert html_response(conn, 200) =~ "Listing games" end - test "creates resource and redirects when data is valid", %{conn: conn} do + test "creates game and redirects when data is valid", %{conn: conn} do opponent = insert(:user, %{email: "daruk@goron.city"}) attrs = %{"opponent_id" => opponent.id} @@ -33,6 +34,21 @@ defmodule ChessWeb.GameControllerTest do assert redirected_to(conn) == game_path(conn, :show, game) end + test "sends and email when game is created", %{conn: conn} do + opponent = insert(:user, %{name: "Daruk", email: "daruk@goron.city"}) + attrs = %{"opponent_id" => opponent.id} + + user = insert(:user) + + conn + |> login(user) + |> post(game_path(conn, :create), game: attrs) + + assert_email_delivered_with( + to: [{opponent.name, opponent.email}] + ) + end + test "shows chosen game", %{conn: conn} do user = insert(:user) opponent = insert(:user, %{email: "revali@rito.village"}) @@ -71,7 +87,7 @@ defmodule ChessWeb.GameControllerTest do end end - test "deletes chosen resource", %{conn: conn} do + test "deletes game", %{conn: conn} do game = Repo.insert! %Game{} user = insert(:user) conn = login(conn, user)