defmodule Mobilizon.Service.Workers.NotificationTest do @moduledoc """ Test the scheduler module """ alias Mobilizon.Actors.Actor alias Mobilizon.Events alias Mobilizon.Events.{Event, Participant} alias Mobilizon.Service.Workers.Notification alias Mobilizon.Users.User alias Mobilizon.Web.Email.Notification, as: NotificationMailer use Mobilizon.DataCase use Bamboo.Test import Mobilizon.Factory describe "A before_event_notification job sends an email" do test "if the user is still participating" do %User{id: user_id} = user = insert(:user) settings = insert(:settings, user_id: user_id, notification_before_event: true ) user = Map.put(user, :settings, settings) %Actor{} = actor = insert(:actor, user: user) %Participant{id: participant_id} = participant = insert(:participant, role: :participant, actor: actor) Notification.perform(%Oban.Job{ args: %{"op" => "before_event_notification", "participant_id" => participant_id} }) assert_delivered_email( NotificationMailer.before_event_notification( participant.actor.user.email, participant ) ) end test "unless the person is no longer participating" do %Event{id: event_id} = insert(:event) %User{} = user = insert(:user) %Actor{id: actor_id} = insert(:actor, user: user) {:ok, %Participant{id: participant_id} = participant} = Events.create_participant(%{actor_id: actor_id, event_id: event_id, role: :participant}) actor = Map.put(participant.actor, :user, user) participant = Map.put(participant, :actor, actor) assert {:ok, %{participant: %Participant{}}} = Events.delete_participant(participant) Notification.perform(%Oban.Job{ args: %{"op" => "before_event_notification", "participant_id" => participant_id} }) refute_delivered_email( NotificationMailer.before_event_notification( participant.actor.user.email, participant ) ) end test "unless the event has been cancelled" do %Event{} = event = insert(:event, status: :cancelled) %Participant{id: participant_id} = participant = insert(:participant, role: :participant, event: event) Notification.perform(%Oban.Job{ args: %{"op" => "before_event_notification", "participant_id" => participant_id} }) refute_delivered_email( NotificationMailer.before_event_notification( participant.actor.user.email, participant ) ) end end describe "A on_day_notification job sends an email" do test "if the user is still participating" do %User{id: user_id} = user = insert(:user) settings = insert(:settings, user_id: user_id, notification_on_day: true, timezone: "Europe/Paris") user = Map.put(user, :settings, settings) %Actor{} = actor = insert(:actor, user: user) %Participant{} = participant = insert(:participant, role: :participant, actor: actor) Notification.perform(%Oban.Job{ args: %{"op" => "on_day_notification", "user_id" => user_id} }) assert_delivered_email( NotificationMailer.on_day_notification( user, [participant], 1 ) ) end test "unless the person is no longer participating" do %Event{id: event_id} = insert(:event) %User{id: user_id} = user = insert(:user) settings = insert(:settings, user_id: user_id, notification_on_day: true, timezone: "Europe/Paris") user = Map.put(user, :settings, settings) %Actor{} = actor = insert(:actor, user: user) {:ok, %Participant{} = participant} = Events.create_participant(%{actor_id: actor.id, event_id: event_id, role: :participant}) actor = Map.put(participant.actor, :user, user) participant = Map.put(participant, :actor, actor) assert {:ok, %{participant: %Participant{}}} = Events.delete_participant(participant) Notification.perform(%Oban.Job{ args: %{"op" => "on_day_notification", "user_id" => user_id} }) refute_delivered_email( NotificationMailer.on_day_notification( user, [participant], 1 ) ) end test "unless the event has been cancelled" do %User{id: user_id} = user = insert(:user) settings = insert(:settings, user_id: user_id, notification_on_day: true, timezone: "Europe/Paris") user = Map.put(user, :settings, settings) %Actor{} = actor = insert(:actor, user: user) %Event{} = event = insert(:event, status: :cancelled) %Participant{} = participant = insert(:participant, role: :participant, event: event, actor: actor) Notification.perform(%Oban.Job{ args: %{"op" => "on_day_notification", "user_id" => user_id} }) refute_delivered_email( NotificationMailer.on_day_notification( user, [participant], 1 ) ) end test "with a lot of events" do %User{id: user_id} = user = insert(:user) settings = insert(:settings, user_id: user_id, notification_on_day: true, timezone: "Europe/Paris") user = Map.put(user, :settings, settings) %Actor{} = actor = insert(:actor, user: user) participants = Enum.reduce(0..10, [], fn _i, acc -> %Participant{} = participant = insert(:participant, role: :participant, actor: actor) acc ++ [participant] end) Notification.perform(%Oban.Job{ args: %{"op" => "on_day_notification", "user_id" => user_id} }) refute_delivered_email( NotificationMailer.on_day_notification( user, participants, 3 ) ) end end describe "A weekly_notification job sends an email" do test "if the user is still participating" do %User{id: user_id} = user = insert(:user) settings = insert(:settings, user_id: user_id, notification_each_week: true, timezone: "Europe/Paris") user = Map.put(user, :settings, settings) %Actor{} = actor = insert(:actor, user: user) %Participant{} = participant = insert(:participant, role: :participant, actor: actor) Notification.perform(%Oban.Job{ args: %{"op" => "weekly_notification", "user_id" => user_id} }) assert_delivered_email( NotificationMailer.weekly_notification( user, [participant], 1 ) ) end test "unless the person is no longer participating" do %Event{id: event_id} = insert(:event) %User{id: user_id} = user = insert(:user) settings = insert(:settings, user_id: user_id, notification_each_week: true, timezone: "Europe/Paris") user = Map.put(user, :settings, settings) %Actor{} = actor = insert(:actor, user: user) {:ok, %Participant{} = participant} = Events.create_participant(%{actor_id: actor.id, event_id: event_id, role: :participant}) actor = Map.put(participant.actor, :user, user) participant = Map.put(participant, :actor, actor) assert {:ok, %{participant: %Participant{}}} = Events.delete_participant(participant) Notification.perform(%Oban.Job{ args: %{"op" => "weekly_notification", "user_id" => user_id} }) refute_delivered_email( NotificationMailer.weekly_notification( user, [participant], 1 ) ) end test "unless the event has been cancelled" do %User{id: user_id} = user = insert(:user) settings = insert(:settings, user_id: user_id, notification_each_week: true, timezone: "Europe/Paris") user = Map.put(user, :settings, settings) %Actor{} = actor = insert(:actor, user: user) %Event{} = event = insert(:event, status: :cancelled) %Participant{} = participant = insert(:participant, role: :participant, event: event, actor: actor) Notification.perform(%Oban.Job{ args: %{"op" => "weekly_notification", "user_id" => user_id} }) refute_delivered_email( NotificationMailer.weekly_notification( user, [participant], 1 ) ) end test "with a lot of events" do %User{id: user_id} = user = insert(:user) settings = insert(:settings, user_id: user_id, notification_each_week: true, timezone: "Europe/Paris") user = Map.put(user, :settings, settings) %Actor{} = actor = insert(:actor, user: user) participants = Enum.reduce(0..10, [], fn _i, acc -> %Participant{} = participant = insert(:participant, role: :participant, actor: actor) acc ++ [participant] end) Notification.perform(%Oban.Job{ args: %{"op" => "weekly_notification", "user_id" => user_id} }) refute_delivered_email( NotificationMailer.weekly_notification( user, participants, 3 ) ) end end describe "A pending_participation_notification job sends an email" do test "if there are participants to approve" do %User{id: user_id} = user = insert(:user) %Event{id: event_id} = event = insert(:event) %Participant{} = insert(:participant, event: event, role: :not_approved) %Participant{} = insert(:participant, event: event, role: :not_approved) Notification.perform(%Oban.Job{ args: %{ "op" => "pending_participation_notification", "user_id" => user_id, "event_id" => event_id } }) assert_delivered_email( NotificationMailer.pending_participation_notification( user, event, 2 ) ) end end end