diff --git a/src/app/EventLog.php b/src/app/EventLog.php --- a/src/app/EventLog.php +++ b/src/app/EventLog.php @@ -25,6 +25,7 @@ public const TYPE_SUSPENDED = 1; public const TYPE_UNSUSPENDED = 2; public const TYPE_COMMENT = 3; + public const TYPE_MAILSENT = 4; /** @var array The attributes that are mass assignable */ protected $fillable = [ @@ -104,6 +105,8 @@ return \trans('app.event-unsuspended'); case self::TYPE_COMMENT: return \trans('app.event-comment'); + case self::TYPE_MAILSENT: + return \trans('app.event-mailsent'); default: return null; } diff --git a/src/app/Mail/DegradedAccountReminder.php b/src/app/Mail/DegradedAccountReminder.php --- a/src/app/Mail/DegradedAccountReminder.php +++ b/src/app/Mail/DegradedAccountReminder.php @@ -6,27 +6,18 @@ use App\User; use App\Utils; use App\Wallet; -use Illuminate\Bus\Queueable; -use Illuminate\Mail\Mailable; -use Illuminate\Queue\SerializesModels; class DegradedAccountReminder extends Mailable { - use Queueable; - use SerializesModels; - /** @var \App\Wallet A wallet with a negative balance */ protected $wallet; - /** @var \App\User A wallet controller to whom the email is being sent */ - protected $user; - /** * Create a new message instance. * * @param \App\Wallet $wallet A wallet - * @param \App\User $user An email recipient + * @param \App\User $user A wallet controller to whom the email is being sent * * @return void */ diff --git a/src/app/Mail/Helper.php b/src/app/Mail/Helper.php --- a/src/app/Mail/Helper.php +++ b/src/app/Mail/Helper.php @@ -2,8 +2,8 @@ namespace App\Mail; +use App\EventLog; use App\Tenant; -use Illuminate\Mail\Mailable; use Illuminate\Support\Facades\Mail; class Helper @@ -11,8 +11,8 @@ /** * Render the mail template. * - * @param \Illuminate\Mail\Mailable $mail The mailable object - * @param string $type Output format ('html' or 'text') + * @param Mailable $mail The mailable object + * @param string $type Output format ('html' or 'text') * * @return string HTML or Plain Text output */ @@ -25,7 +25,9 @@ $mailer = \Illuminate\Container\Container::getInstance()->make('mailer'); return $mailer->render(['text' => $mail->textView], $mail->buildViewData()); - } elseif ($type != 'html') { + } + + if ($type != 'html') { throw new \Exception("Unsupported output format"); } @@ -44,25 +46,19 @@ */ public static function sendMail(Mailable $mail, $tenantId = null, array $params = []): void { - $class = explode("\\", get_class($mail)); - $class = end($class); - - $getRecipients = function () use ($params) { - $recipients = []; - - // For now we do not support addresses + names, only addresses - foreach (['to', 'cc'] as $idx) { - if (!empty($params[$idx])) { - if (is_array($params[$idx])) { - $recipients = array_merge($recipients, $params[$idx]); - } else { - $recipients[] = $params[$idx]; - } + $class = class_basename(get_class($mail)); + $recipients = []; + + // For now we do not support addresses + names, only addresses + foreach (['to', 'cc'] as $idx) { + if (!empty($params[$idx])) { + if (is_array($params[$idx])) { + $recipients = array_merge($recipients, $params[$idx]); + } else { + $recipients[] = $params[$idx]; } } - - return implode(', ', $recipients); - }; + } try { if (!empty($params['to'])) { @@ -88,12 +84,13 @@ Mail::send($mail); - $msg = sprintf("[%s] Sent mail to %s%s", $class, $getRecipients(), $params['add'] ?? ''); - - \Log::info($msg); + if ($user = $mail->getUser()) { + $comment = "[{$class}] " . $mail->getSubject(); + EventLog::createFor($user, EventLog::TYPE_MAILSENT, $comment, ['recipients' => $recipients]); + } } catch (\Exception $e) { $format = "[%s] Failed to send mail to %s%s: %s"; - $msg = sprintf($format, $class, $getRecipients(), $params['add'] ?? '', $e->getMessage()); + $msg = sprintf($format, $class, implode(', ', $recipients), $params['add'] ?? '', $e->getMessage()); \Log::error($msg); throw $e; diff --git a/src/app/Mail/Mailable.php b/src/app/Mail/Mailable.php new file mode 100644 --- /dev/null +++ b/src/app/Mail/Mailable.php @@ -0,0 +1,55 @@ +user; + } + + /** + * Returns the mail subject. + * + * @return string Mail subject + */ + public function getSubject(): string + { + if ($this->subject) { + return $this->subject; + } + + // Subject property is not available before build() method was called + // i.e. before Mail::send(). + // It's also not available when using Mail::fake(). + // This is essentially why we have getSubject() method. + + $class = class_basename(static::class); + + if ($this->user) { + $appName = Tenant::getConfig($this->user->tenant_id, 'app.name'); + } else { + $appName = \config('app.name'); + } + + return \trans('mail.' . strtolower($class) . '-subject', ['site' => $appName]); + } +} diff --git a/src/app/Mail/NegativeBalance.php b/src/app/Mail/NegativeBalance.php --- a/src/app/Mail/NegativeBalance.php +++ b/src/app/Mail/NegativeBalance.php @@ -6,27 +6,18 @@ use App\User; use App\Utils; use App\Wallet; -use Illuminate\Bus\Queueable; -use Illuminate\Mail\Mailable; -use Illuminate\Queue\SerializesModels; class NegativeBalance extends Mailable { - use Queueable; - use SerializesModels; - /** @var \App\Wallet A wallet with a negative balance */ protected $wallet; - /** @var \App\User A wallet controller to whom the email is being sent */ - protected $user; - /** * Create a new message instance. * * @param \App\Wallet $wallet A wallet - * @param \App\User $user An email recipient + * @param \App\User $user A wallet controller to whom the email is being sent * * @return void */ diff --git a/src/app/Mail/NegativeBalanceDegraded.php b/src/app/Mail/NegativeBalanceDegraded.php --- a/src/app/Mail/NegativeBalanceDegraded.php +++ b/src/app/Mail/NegativeBalanceDegraded.php @@ -7,27 +7,18 @@ use App\User; use App\Utils; use App\Wallet; -use Illuminate\Bus\Queueable; -use Illuminate\Mail\Mailable; -use Illuminate\Queue\SerializesModels; class NegativeBalanceDegraded extends Mailable { - use Queueable; - use SerializesModels; - /** @var \App\Wallet A wallet with a negative balance */ protected $wallet; - /** @var \App\User A wallet controller to whom the email is being sent */ - protected $user; - /** * Create a new message instance. * * @param \App\Wallet $wallet A wallet - * @param \App\User $user An email recipient + * @param \App\User $user A wallet controller to whom the email is being sent * * @return void */ diff --git a/src/app/Mail/NegativeBalanceReminderDegrade.php b/src/app/Mail/NegativeBalanceReminderDegrade.php --- a/src/app/Mail/NegativeBalanceReminderDegrade.php +++ b/src/app/Mail/NegativeBalanceReminderDegrade.php @@ -7,27 +7,18 @@ use App\User; use App\Utils; use App\Wallet; -use Illuminate\Bus\Queueable; -use Illuminate\Mail\Mailable; -use Illuminate\Queue\SerializesModels; class NegativeBalanceReminderDegrade extends Mailable { - use Queueable; - use SerializesModels; - /** @var \App\Wallet A wallet with a negative balance */ protected $wallet; - /** @var \App\User A wallet controller to whom the email is being sent */ - protected $user; - /** * Create a new message instance. * * @param \App\Wallet $wallet A wallet - * @param \App\User $user An email recipient + * @param \App\User $user A wallet controller to whom the email is being sent * * @return void */ @@ -48,7 +39,7 @@ $supportUrl = Tenant::getConfig($this->user->tenant_id, 'app.support_url'); $threshold = WalletCheck::threshold($this->wallet, WalletCheck::THRESHOLD_DEGRADE); - $subject = \trans('mail.negativebalancereminder-subject', ['site' => $appName]); + $subject = \trans('mail.negativebalancereminderdegrade-subject', ['site' => $appName]); $this->view('emails.html.negative_balance_reminder_degrade') ->text('emails.plain.negative_balance_reminder_degrade') diff --git a/src/app/Mail/PasswordExpirationReminder.php b/src/app/Mail/PasswordExpirationReminder.php --- a/src/app/Mail/PasswordExpirationReminder.php +++ b/src/app/Mail/PasswordExpirationReminder.php @@ -5,19 +5,9 @@ use App\Tenant; use App\User; use App\Utils; -use Illuminate\Bus\Queueable; -use Illuminate\Mail\Mailable; -use Illuminate\Queue\SerializesModels; -use Illuminate\Support\Str; class PasswordExpirationReminder extends Mailable { - use Queueable; - use SerializesModels; - - /** @var \App\User The user object */ - protected $user; - /** @var string Password expiration date */ protected $expiresOn; @@ -78,4 +68,25 @@ return Helper::render($mail, $type); } + + /** + * Returns the mail subject. + * + * @return string Mail subject + */ + public function getSubject(): string + { + if ($this->subject) { + return $this->subject; + } + + $appName = Tenant::getConfig($this->user->tenant_id, 'app.name'); + + $params = [ + 'site' => $appName, + 'date' => $this->expiresOn, + ]; + + return \trans('mail.passwordexpiration-subject', $params); + } } diff --git a/src/app/Mail/PasswordReset.php b/src/app/Mail/PasswordReset.php --- a/src/app/Mail/PasswordReset.php +++ b/src/app/Mail/PasswordReset.php @@ -6,16 +6,10 @@ use App\User; use App\Utils; use App\VerificationCode; -use Illuminate\Bus\Queueable; -use Illuminate\Mail\Mailable; -use Illuminate\Queue\SerializesModels; use Illuminate\Support\Str; class PasswordReset extends Mailable { - use Queueable; - use SerializesModels; - /** @var \App\VerificationCode A verification code object */ protected $code; @@ -30,6 +24,7 @@ public function __construct(VerificationCode $code) { $this->code = $code; + $this->user = $this->code->user; } /** @@ -39,11 +34,11 @@ */ public function build() { - $appName = Tenant::getConfig($this->code->user->tenant_id, 'app.name'); + $appName = Tenant::getConfig($this->user->tenant_id, 'app.name'); $href = Utils::serviceUrl( sprintf('/password-reset/%s-%s', $this->code->short_code, $this->code->code), - $this->code->user->tenant_id + $this->user->tenant_id ); $this->view('emails.html.password_reset') @@ -54,7 +49,7 @@ 'code' => $this->code->code, 'short_code' => $this->code->short_code, 'link' => sprintf('%s', $href, $href), - 'username' => $this->code->user->name(true) + 'username' => $this->user->name(true) ]); return $this; diff --git a/src/app/Mail/PaymentFailure.php b/src/app/Mail/PaymentFailure.php --- a/src/app/Mail/PaymentFailure.php +++ b/src/app/Mail/PaymentFailure.php @@ -6,27 +6,18 @@ use App\Tenant; use App\User; use App\Utils; -use Illuminate\Bus\Queueable; -use Illuminate\Mail\Mailable; -use Illuminate\Queue\SerializesModels; class PaymentFailure extends Mailable { - use Queueable; - use SerializesModels; - /** @var \App\Payment A payment operation */ protected $payment; - /** @var \App\User A wallet controller to whom the email is being send */ - protected $user; - /** * Create a new message instance. * * @param \App\Payment $payment A payment operation - * @param \App\User $user An email recipient + * @param \App\User $user A wallet controller to whom the email is being sent * * @return void */ diff --git a/src/app/Mail/PaymentMandateDisabled.php b/src/app/Mail/PaymentMandateDisabled.php --- a/src/app/Mail/PaymentMandateDisabled.php +++ b/src/app/Mail/PaymentMandateDisabled.php @@ -6,27 +6,18 @@ use App\User; use App\Utils; use App\Wallet; -use Illuminate\Bus\Queueable; -use Illuminate\Mail\Mailable; -use Illuminate\Queue\SerializesModels; class PaymentMandateDisabled extends Mailable { - use Queueable; - use SerializesModels; - /** @var \App\Wallet A wallet for which the mandate has been disabled */ protected $wallet; - /** @var \App\User A wallet controller to whom the email is being send */ - protected $user; - /** * Create a new message instance. * * @param \App\Wallet $wallet A wallet that has been charged - * @param \App\User $user An email recipient + * @param \App\User $user A wallet controller to whom the email is being sent * * @return void */ diff --git a/src/app/Mail/PaymentSuccess.php b/src/app/Mail/PaymentSuccess.php --- a/src/app/Mail/PaymentSuccess.php +++ b/src/app/Mail/PaymentSuccess.php @@ -6,27 +6,18 @@ use App\Tenant; use App\User; use App\Utils; -use Illuminate\Bus\Queueable; -use Illuminate\Mail\Mailable; -use Illuminate\Queue\SerializesModels; class PaymentSuccess extends Mailable { - use Queueable; - use SerializesModels; - /** @var \App\Payment A payment operation */ protected $payment; - /** @var \App\User A wallet controller to whom the email is being send */ - protected $user; - /** * Create a new message instance. * * @param \App\Payment $payment A payment operation - * @param \App\User $user An email recipient + * @param \App\User $user A wallet controller to whom the email is being sent * * @return void */ diff --git a/src/app/Mail/SignupInvitation.php b/src/app/Mail/SignupInvitation.php --- a/src/app/Mail/SignupInvitation.php +++ b/src/app/Mail/SignupInvitation.php @@ -5,16 +5,10 @@ use App\SignupInvitation as SI; use App\Tenant; use App\Utils; -use Illuminate\Bus\Queueable; -use Illuminate\Mail\Mailable; -use Illuminate\Queue\SerializesModels; use Illuminate\Support\Str; class SignupInvitation extends Mailable { - use Queueable; - use SerializesModels; - /** @var \App\SignupInvitation A signup invitation object */ protected $invitation; diff --git a/src/app/Mail/SignupVerification.php b/src/app/Mail/SignupVerification.php --- a/src/app/Mail/SignupVerification.php +++ b/src/app/Mail/SignupVerification.php @@ -4,16 +4,10 @@ use App\SignupCode; use App\Utils; -use Illuminate\Bus\Queueable; -use Illuminate\Mail\Mailable; -use Illuminate\Queue\SerializesModels; use Illuminate\Support\Str; class SignupVerification extends Mailable { - use Queueable; - use SerializesModels; - /** @var SignupCode A signup verification code object */ protected $code; @@ -47,9 +41,9 @@ } $username = trim($username); - $this->view('emails.html.signup_code') - ->text('emails.plain.signup_code') - ->subject(\trans('mail.signupcode-subject', ['site' => \config('app.name')])) + $this->view('emails.html.signup_verification') + ->text('emails.plain.signup_verification') + ->subject(\trans('mail.signupverification-subject', ['site' => \config('app.name')])) ->with([ 'site' => \config('app.name'), 'username' => $username ?: 'User', diff --git a/src/app/Mail/TrialEnd.php b/src/app/Mail/TrialEnd.php --- a/src/app/Mail/TrialEnd.php +++ b/src/app/Mail/TrialEnd.php @@ -5,29 +5,19 @@ use App\Tenant; use App\User; use App\Utils; -use Illuminate\Bus\Queueable; -use Illuminate\Mail\Mailable; -use Illuminate\Queue\SerializesModels; class TrialEnd extends Mailable { - use Queueable; - use SerializesModels; - - /** @var \App\User An account owner (account) */ - protected $account; - - /** * Create a new message instance. * - * @param \App\User $account An account owner (account) + * @param \App\User $user An account owner * * @return void */ - public function __construct(User $account) + public function __construct(User $user) { - $this->account = $account; + $this->user = $user; } /** @@ -37,9 +27,9 @@ */ public function build() { - $appName = Tenant::getConfig($this->account->tenant_id, 'app.name'); - $paymentUrl = Tenant::getConfig($this->account->tenant_id, 'app.kb.payment_system'); - $supportUrl = Tenant::getConfig($this->account->tenant_id, 'app.support_url'); + $appName = Tenant::getConfig($this->user->tenant_id, 'app.name'); + $paymentUrl = Tenant::getConfig($this->user->tenant_id, 'app.kb.payment_system'); + $supportUrl = Tenant::getConfig($this->user->tenant_id, 'app.support_url'); $subject = \trans('mail.trialend-subject', ['site' => $appName]); @@ -49,9 +39,9 @@ ->with([ 'site' => $appName, 'subject' => $subject, - 'username' => $this->account->name(true), + 'username' => $this->user->name(true), 'paymentUrl' => $paymentUrl, - 'supportUrl' => Utils::serviceUrl($supportUrl, $this->account->tenant_id), + 'supportUrl' => Utils::serviceUrl($supportUrl, $this->user->tenant_id), ]); return $this; diff --git a/src/resources/lang/en/app.php b/src/resources/lang/en/app.php --- a/src/resources/lang/en/app.php +++ b/src/resources/lang/en/app.php @@ -26,6 +26,7 @@ 'event-suspended' => 'Suspended', 'event-unsuspended' => 'Unsuspended', 'event-comment' => 'Commented', + 'event-mailsent' => 'Mail Sent', 'mandate-delete-success' => 'The auto-payment has been removed.', 'mandate-update-success' => 'The auto-payment has been updated.', diff --git a/src/resources/lang/en/mail.php b/src/resources/lang/en/mail.php --- a/src/resources/lang/en/mail.php +++ b/src/resources/lang/en/mail.php @@ -32,10 +32,10 @@ . "Consider setting up an automatic payment to avoid messages like this in the future.", 'negativebalance-body-ext' => "Settle up to keep your account running:", - 'negativebalancereminder-subject' => ":site Payment Reminder", - 'negativebalancereminder-body' => "It has probably skipped your attention that you are behind on paying for your :site account. " + 'negativebalancereminderdegrade-subject' => ":site Payment Reminder", + 'negativebalancereminderdegrade-body' => "It has probably skipped your attention that you are behind on paying for your :site account. " . "Consider setting up an automatic payment to avoid messages like this in the future.", - 'negativebalancereminder-body-ext' => "Settle up to keep your account running:", + 'negativebalancereminderdegrade-body-ext' => "Settle up to keep your account running:", 'negativebalancereminderdegrade-body-warning' => "Please, be aware that your account will be degraded " . "if your account balance is not settled by :date.", @@ -78,9 +78,9 @@ 'support' => "Special circumstances? Something is wrong with a charge?\n" . ":site Support is here to help.", - 'signupcode-subject' => ":site Registration", - 'signupcode-body1' => "This is your verification code for the :site registration process:", - 'signupcode-body2' => "You can also click the link below to continue the registration process:", + 'signupverification-subject' => ":site Registration", + 'signupverification-body1' => "This is your verification code for the :site registration process:", + 'signupverification-body2' => "You can also click the link below to continue the registration process:", 'signupinvitation-subject' => ":site Invitation", 'signupinvitation-header' => "Hi,", diff --git a/src/resources/lang/fr/mail.php b/src/resources/lang/fr/mail.php --- a/src/resources/lang/fr/mail.php +++ b/src/resources/lang/fr/mail.php @@ -32,10 +32,10 @@ . " Veillez à mettre en place un auto-paiement pour éviter de tel avertissement comme celui-ci dans le future.", 'negativebalance-body-ext' => "Régler votre compte pour le maintenir en fontion:", - 'negativebalancereminder-subject' => ":site Rappel de Paiement", - 'negativebalancereminder-body' => "Vous n'avez peut-être pas rendu compte que vous êtes en retard avec votre paiement pour :site compte." + 'negativebalancereminderdegrade-subject' => ":site Rappel de Paiement", + 'negativebalancereminderdegrade-body' => "Vous n'avez peut-être pas rendu compte que vous êtes en retard avec votre paiement pour :site compte." . " Veillez à mettre en place un auto-paiement pour éviter de tel avertissement comme celui-ci dans le future.", - 'negativebalancereminder-body-ext' => "Régler votre compte pour le maintenir en fontion:", + 'negativebalancereminderdegrade-body-ext' => "Régler votre compte pour le maintenir en fontion:", 'negativebalancereminderdegrade-body-warning' => "Veuillez noter que votre compte sera dégradé" . " si le solde de votre compte n'est pas réglé avant le :date.", @@ -75,9 +75,9 @@ 'support' => "Cas particulier? Il y a un probléme avec une charge?\n" . ":site Le support reste à votre disposition.", - 'signupcode-subject' => ":site Enregistrement", - 'signupcode-body1' => "Voici votre code de vérification pour le :site registration process:", - 'signupcode-body2' => "Vous pouvez également continuer avec le processus d'enregistrement en cliquant sur le lien ci-dessous:", + 'signupverification-subject' => ":site Enregistrement", + 'signupverification-body1' => "Voici votre code de vérification pour le :site registration process:", + 'signupverification-body2' => "Vous pouvez également continuer avec le processus d'enregistrement en cliquant sur le lien ci-dessous:", 'signupinvitation-subject' => ":site Invitation", 'signupinvitation-header' => "Salut,", diff --git a/src/resources/views/emails/html/negative_balance_reminder_degrade.blade.php b/src/resources/views/emails/html/negative_balance_reminder_degrade.blade.php --- a/src/resources/views/emails/html/negative_balance_reminder_degrade.blade.php +++ b/src/resources/views/emails/html/negative_balance_reminder_degrade.blade.php @@ -6,8 +6,8 @@

{{ __('mail.header', ['name' => $username]) }}

-

{{ __('mail.negativebalancereminder-body', ['site' => $site]) }}

-

{{ __('mail.negativebalancereminder-body-ext', ['site' => $site]) }}

+

{{ __('mail.negativebalancereminderdegrade-body', ['site' => $site]) }}

+

{{ __('mail.negativebalancereminderdegrade-body-ext', ['site' => $site]) }}

{{ $walletUrl }}

{{ __('mail.negativebalancereminderdegrade-body-warning', ['site' => $site, 'date' => $date]) }}

diff --git a/src/resources/views/emails/html/signup_code.blade.php b/src/resources/views/emails/html/signup_verification.blade.php rename from src/resources/views/emails/html/signup_code.blade.php rename to src/resources/views/emails/html/signup_verification.blade.php --- a/src/resources/views/emails/html/signup_code.blade.php +++ b/src/resources/views/emails/html/signup_verification.blade.php @@ -6,11 +6,11 @@

{{ __('mail.header', ['name' => $username]) }}

-

{{ __('mail.signupcode-body1', ['site' => $site]) }}

+

{{ __('mail.signupverification-body1', ['site' => $site]) }}

{!! $short_code !!}

-

{{ __('mail.signupcode-body2') }}

+

{{ __('mail.signupverification-body2') }}

{!! $href !!}

diff --git a/src/resources/views/emails/plain/negative_balance_reminder_degrade.blade.php b/src/resources/views/emails/plain/negative_balance_reminder_degrade.blade.php --- a/src/resources/views/emails/plain/negative_balance_reminder_degrade.blade.php +++ b/src/resources/views/emails/plain/negative_balance_reminder_degrade.blade.php @@ -1,8 +1,8 @@ {!! __('mail.header', ['name' => $username]) !!} -{!! __('mail.negativebalancereminder-body', ['site' => $site]) !!} +{!! __('mail.negativebalancereminderdegrade-body', ['site' => $site]) !!} -{!! __('mail.negativebalancereminder-body-ext', ['site' => $site]) !!} +{!! __('mail.negativebalancereminderdegrade-body-ext', ['site' => $site]) !!} {!! $walletUrl !!} diff --git a/src/resources/views/emails/plain/signup_code.blade.php b/src/resources/views/emails/plain/signup_verification.blade.php rename from src/resources/views/emails/plain/signup_code.blade.php rename to src/resources/views/emails/plain/signup_verification.blade.php --- a/src/resources/views/emails/plain/signup_code.blade.php +++ b/src/resources/views/emails/plain/signup_verification.blade.php @@ -1,10 +1,10 @@ {!! __('mail.header', ['name' => $username]) !!} -{!! __('mail.signupcode-body1', ['site' => $site]) !!} +{!! __('mail.signupverification-body1', ['site' => $site]) !!} {!! $short_code !!} -{!! __('mail.signupcode-body2') !!} +{!! __('mail.signupverification-body2') !!} {!! $href !!} diff --git a/src/tests/Unit/Mail/DegradedAccountReminderTest.php b/src/tests/Unit/Mail/DegradedAccountReminderTest.php --- a/src/tests/Unit/Mail/DegradedAccountReminderTest.php +++ b/src/tests/Unit/Mail/DegradedAccountReminderTest.php @@ -39,4 +39,19 @@ $this->assertTrue(strpos($plain, "your account is a free account") > 0); $this->assertTrue(strpos($plain, "$appName Team") > 0); } + + /** + * Test getSubject() and getUser() + */ + public function testGetSubjectAndUser(): void + { + $user = $this->getTestUser('ned@kolab.org'); + $wallet = $user->wallets->first(); + $appName = $user->tenant->title; + + $mail = new DegradedAccountReminder($wallet, $user); + + $this->assertSame("$appName Reminder: Your account is free", $mail->getSubject()); + $this->assertSame($user, $mail->getUser()); + } } diff --git a/src/tests/Unit/Mail/HelperTest.php b/src/tests/Unit/Mail/HelperTest.php --- a/src/tests/Unit/Mail/HelperTest.php +++ b/src/tests/Unit/Mail/HelperTest.php @@ -2,6 +2,7 @@ namespace Tests\Unit\Mail; +use App\EventLog; use App\Mail\Helper; use App\User; use Illuminate\Support\Facades\Mail; @@ -36,6 +37,7 @@ */ public function testSendMail(): void { + EventLog::truncate(); Mail::fake(); $tenant = \App\Tenant::whereNotIn('id', [1])->first(); @@ -90,7 +92,20 @@ && $mail->hasReplyTo('replyto@test.com', 'replyto name'); }); - // TODO: Test somehow log entries, maybe with timacdonald/log-fake package + // No EventLog entries up to this point + $this->assertSame(0, EventLog::count()); + + // Assert EventLog entry + $user = $this->getTestUser('mail-helper-test@kolabnow.com'); + $mail = new \App\Mail\TrialEnd($user); + + Helper::sendMail($mail, $tenant->id, ['to' => 'to@test.com', 'cc' => 'cc@test.com']); + + $event = EventLog::where('object_id', $user->id)->where('object_type', User::class)->first(); + $this->assertSame(EventLog::TYPE_MAILSENT, $event->type); + $this->assertSame(['recipients' => ['to@test.com', 'cc@test.com']], $event->data); + $this->assertSame("[TrialEnd] Kolab Now: Your trial phase has ended", $event->comment); + // TODO: Test somehow exception case } diff --git a/src/tests/Unit/Mail/NegativeBalanceDegradedTest.php b/src/tests/Unit/Mail/NegativeBalanceDegradedTest.php --- a/src/tests/Unit/Mail/NegativeBalanceDegradedTest.php +++ b/src/tests/Unit/Mail/NegativeBalanceDegradedTest.php @@ -52,4 +52,19 @@ $this->assertTrue(strpos($plain, "$appName Support") > 0); $this->assertTrue(strpos($plain, "$appName Team") > 0); } + + /** + * Test getSubject() and getUser() + */ + public function testGetSubjectAndUser(): void + { + $user = $this->getTestUser('ned@kolab.org'); + $wallet = $user->wallets->first(); + $appName = $user->tenant->title; + + $mail = new NegativeBalanceDegraded($wallet, $user); + + $this->assertSame("$appName Account Degraded", $mail->getSubject()); + $this->assertSame($user, $mail->getUser()); + } } diff --git a/src/tests/Unit/Mail/NegativeBalanceReminderDegradeTest.php b/src/tests/Unit/Mail/NegativeBalanceReminderDegradeTest.php --- a/src/tests/Unit/Mail/NegativeBalanceReminderDegradeTest.php +++ b/src/tests/Unit/Mail/NegativeBalanceReminderDegradeTest.php @@ -58,4 +58,19 @@ $this->assertTrue(strpos($plain, "$appName Support") > 0); $this->assertTrue(strpos($plain, "$appName Team") > 0); } + + /** + * Test getSubject() and getUser() + */ + public function testGetSubjectAndUser(): void + { + $user = $this->getTestUser('ned@kolab.org'); + $wallet = $user->wallets->first(); + $appName = $user->tenant->title; + + $mail = new NegativeBalanceReminderDegrade($wallet, $user); + + $this->assertSame("$appName Payment Reminder", $mail->getSubject()); + $this->assertSame($user, $mail->getUser()); + } } diff --git a/src/tests/Unit/Mail/NegativeBalanceTest.php b/src/tests/Unit/Mail/NegativeBalanceTest.php --- a/src/tests/Unit/Mail/NegativeBalanceTest.php +++ b/src/tests/Unit/Mail/NegativeBalanceTest.php @@ -49,4 +49,19 @@ $this->assertTrue(strpos($plain, "$appName Support") > 0); $this->assertTrue(strpos($plain, "$appName Team") > 0); } + + /** + * Test getSubject() and getUser() + */ + public function testGetSubjectAndUser(): void + { + $user = new User(); + $wallet = new Wallet(); + $appName = \config('app.name'); + + $mail = new NegativeBalance($wallet, $user); + + $this->assertSame("$appName Payment Required", $mail->getSubject()); + $this->assertSame($user, $mail->getUser()); + } } diff --git a/src/tests/Unit/Mail/PasswordExpirationReminderTest.php b/src/tests/Unit/Mail/PasswordExpirationReminderTest.php --- a/src/tests/Unit/Mail/PasswordExpirationReminderTest.php +++ b/src/tests/Unit/Mail/PasswordExpirationReminderTest.php @@ -40,4 +40,19 @@ $this->assertTrue(strpos($plain, $link) > 0); $this->assertTrue(strpos($plain, $expiresOn) > 0); } + + /** + * Test getSubject() and getUser() + */ + public function testGetSubjectAndUser(): void + { + $user = new User(['name' => 'User Name']); + $appName = \config('app.name'); + $expiresOn = now()->copy()->addDays(7)->toDateString(); + + $mail = new PasswordExpirationReminder($user, $expiresOn); + + $this->assertSame("$appName password expires on $expiresOn", $mail->getSubject()); + $this->assertSame($user, $mail->getUser()); + } } diff --git a/src/tests/Unit/Mail/PasswordResetTest.php b/src/tests/Unit/Mail/PasswordResetTest.php --- a/src/tests/Unit/Mail/PasswordResetTest.php +++ b/src/tests/Unit/Mail/PasswordResetTest.php @@ -45,4 +45,26 @@ $this->assertStringStartsWith("Dear " . $code->user->name(true), $plain); $this->assertTrue(strpos($plain, $link) > 0); } + + /** + * Test getSubject() and getUser() + */ + public function testGetSubjectAndUser(): void + { + $appName = \config('app.name'); + $code = new VerificationCode([ + 'user_id' => 123456789, + 'mode' => 'password-reset', + 'code' => 'code', + 'short_code' => 'short-code', + ]); + + // @phpstan-ignore-next-line + $code->user = new User(['name' => 'User Name']); + + $mail = new PasswordReset($code); + + $this->assertSame("$appName Password Reset", $mail->getSubject()); + $this->assertSame($code->user, $mail->getUser()); + } } diff --git a/src/tests/Unit/Mail/PaymentFailureTest.php b/src/tests/Unit/Mail/PaymentFailureTest.php --- a/src/tests/Unit/Mail/PaymentFailureTest.php +++ b/src/tests/Unit/Mail/PaymentFailureTest.php @@ -48,4 +48,21 @@ $this->assertTrue(strpos($plain, "Something went wrong with auto-payment for your $appName account") > 0); $this->assertTrue(strpos($plain, "$appName Team") > 0); } + + /** + * Test getSubject() and getUser() + */ + public function testGetSubjectAndUser(): void + { + $user = new User(); + $user->id = 1234; + $payment = new Payment(); + $payment->amount = 123; + $appName = \config('app.name'); + + $mail = new PaymentFailure($payment, $user); + + $this->assertSame("$appName Payment Failed", $mail->getSubject()); + $this->assertSame($user, $mail->getUser()); + } } diff --git a/src/tests/Unit/Mail/PaymentMandateDisabledTest.php b/src/tests/Unit/Mail/PaymentMandateDisabledTest.php --- a/src/tests/Unit/Mail/PaymentMandateDisabledTest.php +++ b/src/tests/Unit/Mail/PaymentMandateDisabledTest.php @@ -47,4 +47,20 @@ $this->assertTrue(strpos($plain, "Your $appName account balance") > 0); $this->assertTrue(strpos($plain, "$appName Team") > 0); } + + /** + * Test getSubject() and getUser() + */ + public function testGetSubjectAndUser(): void + { + $user = new User(); + $user->id = 1234; + $wallet = new Wallet(); + $appName = \config('app.name'); + + $mail = new PaymentMandateDisabled($wallet, $user); + + $this->assertSame("$appName Auto-payment Problem", $mail->getSubject()); + $this->assertSame($user, $mail->getUser()); + } } diff --git a/src/tests/Unit/Mail/PaymentSuccessTest.php b/src/tests/Unit/Mail/PaymentSuccessTest.php --- a/src/tests/Unit/Mail/PaymentSuccessTest.php +++ b/src/tests/Unit/Mail/PaymentSuccessTest.php @@ -48,4 +48,21 @@ $this->assertTrue(strpos($plain, "The auto-payment for your $appName account") > 0); $this->assertTrue(strpos($plain, "$appName Team") > 0); } + + /** + * Test getSubject() and getUser() + */ + public function testGetSubjectAndUser(): void + { + $user = new User(); + $user->id = 1234; + $payment = new Payment(); + $payment->amount = 123; + $appName = \config('app.name'); + + $mail = new PaymentSuccess($payment, $user); + + $this->assertSame("$appName Payment Succeeded", $mail->getSubject()); + $this->assertSame($user, $mail->getUser()); + } } diff --git a/src/tests/Unit/Mail/SignupInvitationTest.php b/src/tests/Unit/Mail/SignupInvitationTest.php --- a/src/tests/Unit/Mail/SignupInvitationTest.php +++ b/src/tests/Unit/Mail/SignupInvitationTest.php @@ -38,4 +38,21 @@ $this->assertTrue(strpos($plain, "invited to join $appName") > 0); $this->assertTrue(strpos($plain, $url) > 0); } + + /** + * Test getSubject() and getUser() + */ + public function testGetSubjectAndUser(): void + { + $appName = \config('app.name'); + $invitation = new SI([ + 'id' => 'abc', + 'email' => 'test@email', + ]); + + $mail = new SignupInvitation($invitation); + + $this->assertSame("$appName Invitation", $mail->getSubject()); + $this->assertSame(null, $mail->getUser()); + } } diff --git a/src/tests/Unit/Mail/SignupVerificationTest.php b/src/tests/Unit/Mail/SignupVerificationTest.php --- a/src/tests/Unit/Mail/SignupVerificationTest.php +++ b/src/tests/Unit/Mail/SignupVerificationTest.php @@ -40,4 +40,24 @@ $this->assertStringStartsWith('Dear First Last', $plain); $this->assertTrue(strpos($plain, $url) > 0); } + + /** + * Test getSubject() and getUser() + */ + public function testGetSubjectAndUser(): void + { + $appName = \config('app.name'); + $code = new SignupCode([ + 'code' => 'code', + 'short_code' => 'short-code', + 'email' => 'test@email', + 'first_name' => 'First', + 'last_name' => 'Last', + ]); + + $mail = new SignupVerification($code); + + $this->assertSame("$appName Registration", $mail->getSubject()); + $this->assertSame(null, $mail->getUser()); + } } diff --git a/src/tests/Unit/Mail/TrialEndTest.php b/src/tests/Unit/Mail/TrialEndTest.php --- a/src/tests/Unit/Mail/TrialEndTest.php +++ b/src/tests/Unit/Mail/TrialEndTest.php @@ -46,4 +46,18 @@ $this->assertTrue(strpos($plain, "30 days of free $appName trial") > 0); $this->assertTrue(strpos($plain, "$appName Team") > 0); } + + /** + * Test getSubject() and getUser() + */ + public function testGetSubjectAndUser(): void + { + $user = new User(); + $appName = \config('app.name'); + + $mail = new TrialEnd($user); + + $this->assertSame("$appName: Your trial phase has ended", $mail->getSubject()); + $this->assertSame($user, $mail->getUser()); + } }