diff --git a/app/Http/Controllers/Account/AcceptanceController.php b/app/Http/Controllers/Account/AcceptanceController.php index e29fa7c63b..278d7e2081 100644 --- a/app/Http/Controllers/Account/AcceptanceController.php +++ b/app/Http/Controllers/Account/AcceptanceController.php @@ -338,4 +338,5 @@ class AcceptanceController extends Controller return redirect()->to('account/accept')->with('success', $return_msg); } + } diff --git a/app/Listeners/CheckoutableListener.php b/app/Listeners/CheckoutableListener.php index eb6b738094..7d8b5c1c9d 100644 --- a/app/Listeners/CheckoutableListener.php +++ b/app/Listeners/CheckoutableListener.php @@ -3,13 +3,19 @@ namespace App\Listeners; use App\Events\CheckoutableCheckedOut; +use App\Mail\CheckinAccessoryMail; +use App\Mail\CheckinLicenseMail; +use App\Mail\CheckoutAccessoryMail; +use App\Mail\CheckoutAssetMail; +use App\Mail\CheckinAssetMail; +use App\Mail\CheckoutConsumableMail; +use App\Mail\CheckoutLicenseMail; use App\Models\Accessory; use App\Models\Asset; use App\Models\CheckoutAcceptance; use App\Models\Component; use App\Models\Consumable; use App\Models\LicenseSeat; -use App\Models\Recipients\AdminRecipient; use App\Models\Setting; use App\Models\User; use App\Notifications\CheckinAccessoryNotification; @@ -20,6 +26,7 @@ use App\Notifications\CheckoutAssetNotification; use App\Notifications\CheckoutConsumableNotification; use App\Notifications\CheckoutLicenseSeatNotification; use GuzzleHttp\Exception\ClientException; +use Illuminate\Support\Facades\Mail; use Illuminate\Support\Facades\Notification; use Exception; use Illuminate\Support\Facades\Log; @@ -43,33 +50,42 @@ class CheckoutableListener /** * Make a checkout acceptance and attach it in the notification */ + $settings = Setting::getSettings(); $acceptance = $this->getCheckoutAcceptance($event); - $notifiables = $this->getNotifiables($event); + $adminCcEmailsArray = []; + if($settings->admin_cc_email !== '') { + $adminCcEmail = $settings->admin_cc_email; + $adminCcEmailsArray = array_map('trim', explode(',', $adminCcEmail)); + } + $ccEmails = array_filter($adminCcEmailsArray); + $notifiable = $event->checkedOutTo; + $mailable = $this->getCheckoutMailType($event, $acceptance); // Send email notifications try { - foreach ($notifiables as $notifiable) { - if ($notifiable instanceof User && $notifiable->email != '') { - if (! $event->checkedOutTo->locale){ - Notification::locale(Setting::getSettings()->locale)->send($notifiable, $this->getCheckoutNotification($event, $acceptance)); - } - else { - Notification::send($notifiable, $this->getCheckoutNotification($event, $acceptance)); - } + if (!$event->checkedOutTo->locale){ + $mailable->locale($event->checkedOutTo->locale); } - } - // Send Webhook notification - if ($this->shouldSendWebhookNotification()) { - // Slack doesn't include the URL in its messaging format, so this is needed to hit the endpoint - if (Setting::getSettings()->webhook_selected === 'slack' || Setting::getSettings()->webhook_selected === 'general') { - Notification::route('slack', Setting::getSettings()->webhook_endpoint) - ->notify($this->getCheckoutNotification($event, $acceptance)); - } else { + /** + * Send an email if any of the following conditions are met: + * 1. The asset requires acceptance + * 2. The item has a EULA + * 3. The item should send an email at check-in/check-out + */ + if ($notifiable instanceof User && $notifiable->email != '') { + if ($event->checkoutable->requireAcceptance() || $event->checkoutable->getEula() || + (method_exists($event->checkoutable, 'checkin_email') && $event->checkoutable->checkin_email())) { + Mail::to($notifiable)->cc($ccEmails)->send($mailable); + Log::info('Sending email, Locale: ' . ($event->checkedOutTo->locale ?? 'default')); + } + } + +// Send Webhook notification + if ($this->shouldSendWebhookNotification()) { Notification::route(Setting::getSettings()->webhook_selected, Setting::getSettings()->webhook_endpoint) ->notify($this->getCheckoutNotification($event, $acceptance)); } - } } catch (ClientException $e) { Log::debug("Exception caught during checkout notification: " . $e->getMessage()); } catch (Exception $e) { @@ -103,32 +119,41 @@ class CheckoutableListener } } } + $settings = Setting::getSettings(); + $adminCcEmailsArray = []; + + if($settings->admin_cc_email !== '') { + $adminCcEmail = $settings->admin_cc_email; + $adminCcEmailsArray = array_map('trim', explode(',', $adminCcEmail)); + } + $ccEmails = array_filter($adminCcEmailsArray); + $notifiable = $event->checkedOutTo; + $mailable = $this->getCheckinMailType($event); - $notifiables = $this->getNotifiables($event); // Send email notifications try { - foreach ($notifiables as $notifiable) { - if ($notifiable instanceof User && $notifiable->email != '') { - if (! $event->checkedOutTo->locale){ - Notification::locale(Setting::getSettings()->locale)->send($notifiable, $this->getCheckoutNotification($event, $acceptance)); - } - else { - Notification::send($notifiable, $this->getCheckinNotification($event)); - } + if (!$event->checkedOutTo->locale){ + $mailable->locale($event->checkedOutTo->locale); + } + /** + * Send an email if any of the following conditions are met: + * 1. The asset requires acceptance + * 2. The item has a EULA + * 3. The item should send an email at check-in/check-out + */ + + if ($notifiable instanceof User && $notifiable->email != '') { + if ($event->checkoutable->requireAcceptance() || $event->checkoutable->getEula() || + (method_exists($event->checkoutable, 'checkin_email') && $event->checkoutable->checkin_email())) { + Mail::to($notifiable)->cc($ccEmails)->send($mailable); + Log::info('Sending email, Locale: ' . $event->checkedOutTo->locale); } } // Send Webhook notification if ($this->shouldSendWebhookNotification()) { - // Slack doesn't include the URL in its messaging format, so this is needed to hit the endpoint - if (Setting::getSettings()->webhook_selected === 'slack' || Setting::getSettings()->webhook_selected === 'general') { - Notification::route('slack', Setting::getSettings()->webhook_endpoint) - ->notify($this->getCheckinNotification($event)); - } else { Notification::route(Setting::getSettings()->webhook_selected, Setting::getSettings()->webhook_endpoint) ->notify($this->getCheckinNotification($event)); } - } - } catch (ClientException $e) { Log::warning("Exception caught during checkout notification: " . $e->getMessage()); } catch (Exception $e) { @@ -159,33 +184,6 @@ class CheckoutableListener return $acceptance; } - /** - * Gets the entities to be notified of the passed event - * - * @param Event $event - * @return Collection - */ - private function getNotifiables($event) - { - $notifiables = collect(); - - /** - * Notify who checked out the item as long as the model can route notifications - */ - if (method_exists($event->checkedOutTo, 'routeNotificationFor')) { - $notifiables->push($event->checkedOutTo); - } - - /** - * Notify Admin users if the settings is activated - */ - if ((Setting::getSettings()) && (Setting::getSettings()->admin_cc_email != '')) { - $notifiables->push(new AdminRecipient()); - } - - return $notifiables; - } - /** * Get the appropriate notification for the event * @@ -234,7 +232,7 @@ class CheckoutableListener break; case Consumable::class: $notificationClass = CheckoutConsumableNotification::class; - break; + break; case LicenseSeat::class: $notificationClass = CheckoutLicenseSeatNotification::class; break; @@ -243,6 +241,30 @@ class CheckoutableListener return new $notificationClass($event->checkoutable, $event->checkedOutTo, $event->checkedOutBy, $acceptance, $event->note); } + private function getCheckoutMailType($event, $acceptance){ + $lookup = [ + Accessory::class => CheckoutAccessoryMail::class, + Asset::class => CheckoutAssetMail::class, + LicenseSeat::class => CheckoutLicenseMail::class, + Consumable::class => CheckoutConsumableMail::class, + ]; + $mailable= $lookup[get_class($event->checkoutable)]; + + return new $mailable($event->checkoutable, $event->checkedOutTo, $event->checkedOutBy, $event->note, $acceptance); + + } + private function getCheckinMailType($event){ + $lookup = [ + Accessory::class => CheckinAccessoryMail::class, + Asset::class => CheckinAssetMail::class, + LicenseSeat::class => CheckinLicenseMail::class, + ]; + + $mailable= $lookup[get_class($event->checkoutable)]; + + return new $mailable($event->checkoutable, $event->checkedOutTo, $event->checkedInBy, $event->note); + + } /** * Register the listeners for the subscriber. diff --git a/app/Mail/CheckinAccessoryMail.php b/app/Mail/CheckinAccessoryMail.php new file mode 100644 index 0000000000..fc8d1455f9 --- /dev/null +++ b/app/Mail/CheckinAccessoryMail.php @@ -0,0 +1,70 @@ +item = $accessory; + $this->target = $checkedOutTo; + $this->admin = $checkedInby; + $this->note = $note; + $this->settings = Setting::getSettings(); + } + + /** + * Get the message envelope. + */ + public function envelope(): Envelope + { + $from = new Address(env('MAIL_FROM_ADDR','service@snipe-it.io')); + + return new Envelope( + from: $from, + subject: trans('mail.Accessory_Checkin_Notification'), + ); + } + + /** + * Get the message content definition. + */ + public function content(): Content + { + return new Content( + markdown: 'mail.markdown.checkin-accessory', + with: [ + 'item' => $this->item, + 'admin' => $this->admin, + 'note' => $this->note, + 'target' => $this->target, + ] + ); + } + + /** + * Get the attachments for the message. + * + * @return array + */ + public function attachments(): array + { + return []; + } +} diff --git a/app/Mail/CheckinAssetMail.php b/app/Mail/CheckinAssetMail.php new file mode 100644 index 0000000000..5dd8394a5a --- /dev/null +++ b/app/Mail/CheckinAssetMail.php @@ -0,0 +1,93 @@ +target = $checkedOutTo; + $this->item = $asset; + $this->admin = $checkedInBy; + $this->note = $note; + + $this->settings = Setting::getSettings(); + $this->expected_checkin = ''; + + if ($this->item->expected_checkin) { + $this->expected_checkin = Helper::getFormattedDateObject($this->item->expected_checkin, 'date', + false); + } + } + + /** + * Get the message envelope. + */ + public function envelope(): Envelope + { + $from = new Address(env('MAIL_FROM_ADDR','service@snipe-it.io')); + + return new Envelope( + from: $from, + subject: trans('mail.Asset_Checkin_Notification'), + ); + } + + /** + * Get the mail representation of the notification. + * + * @param mixed $notifiable + * @return Content + */ + public function content(): Content + { + $this->item->load('assetstatus'); + $fields = []; + + // Check if the item has custom fields associated with it + if (($this->item->model) && ($this->item->model->fieldset)) { + $fields = $this->item->model->fieldset->fields; + } + + return new Content( + markdown: 'mail.markdown.checkin-asset', + with: [ + 'item' => $this->item, + 'status' => $this->item->assetstatus?->name, + 'admin' => $this->admin, + 'note' => $this->note, + 'target' => $this->target, + 'fields' => $fields, + 'expected_checkin' => $this->expected_checkin, + ], + ); + } + + /** + * Get the attachments for the message. + * + * @return array + */ + public function attachments(): array + { + return []; + } +} diff --git a/app/Mail/CheckinLicenseMail.php b/app/Mail/CheckinLicenseMail.php new file mode 100644 index 0000000000..97ce4dd3c3 --- /dev/null +++ b/app/Mail/CheckinLicenseMail.php @@ -0,0 +1,70 @@ +target = $checkedOutTo; + $this->item = $licenseSeat->license; + $this->admin = $checkedInBy; + $this->note = $note; + $this->settings = Setting::getSettings(); + } + + /** + * Get the message envelope. + */ + public function envelope(): Envelope + { + $from = new Address(env('MAIL_FROM_ADDR','service@snipe-it.io')); + + return new Envelope( + from: $from, + subject: trans('mail.License_Checkin_Notification'), + ); + } + + /** + * Get the message content definition. + */ + public function content(): Content + { + return new Content( + markdown: 'mail.markdown.checkin-license', + with: [ + 'item' => $this->item, + 'admin' => $this->admin, + 'note' => $this->note, + 'target' => $this->target, + ] + ); + } + + /** + * Get the attachments for the message. + * + * @return array + */ + public function attachments(): array + { + return []; + } +} diff --git a/app/Mail/CheckoutAccessoryMail.php b/app/Mail/CheckoutAccessoryMail.php new file mode 100644 index 0000000000..f297c02754 --- /dev/null +++ b/app/Mail/CheckoutAccessoryMail.php @@ -0,0 +1,82 @@ +item = $accessory; + $this->admin = $checkedOutBy; + $this->note = $note; + $this->checkout_qty = $accessory->checkout_qty; + $this->target = $checkedOutTo; + $this->acceptance = $acceptance; + $this->settings = Setting::getSettings(); + } + + /** + * Get the message envelope. + */ + public function envelope(): Envelope + { + $from = new Address(env('MAIL_FROM_ADDR','service@snipe-it.io')); + + return new Envelope( + from: $from, + subject: (trans('mail.Accessory_Checkout_Notification')), + ); + } + + /** + * Get the message content definition. + */ + public function content(): Content + { + Log::debug($this->item->getImageUrl()); + $eula = $this->item->getEula(); + $req_accept = $this->item->requireAcceptance(); + $accept_url = is_null($this->acceptance) ? null : route('account.accept.item', $this->acceptance); + + return new Content( + markdown: 'mail.markdown.checkout-accessory', + with: [ + 'item' => $this->item, + 'admin' => $this->admin, + 'note' => $this->note, + 'target' => $this->target, + 'eula' => $eula, + 'req_accept' => $req_accept, + 'accept_url' => $accept_url, + 'checkout_qty' => $this->checkout_qty, + ], + ); + } + + /** + * Get the attachments for the message. + * + * @return array + */ + public function attachments(): array + { + return []; + } +} diff --git a/app/Mail/CheckoutAssetMail.php b/app/Mail/CheckoutAssetMail.php new file mode 100644 index 0000000000..fa1290e92d --- /dev/null +++ b/app/Mail/CheckoutAssetMail.php @@ -0,0 +1,110 @@ +item = $asset; + $this->admin = $checkedOutBy; + $this->note = $note; + $this->target = $checkedOutTo; + $this->acceptance = $acceptance; + + $this->settings = Setting::getSettings(); + + $this->last_checkout = ''; + $this->expected_checkin = ''; + + if ($this->item->last_checkout) { + $this->last_checkout = Helper::getFormattedDateObject($this->item->last_checkout, 'date', + false); + } + + if ($this->item->expected_checkin) { + $this->expected_checkin = Helper::getFormattedDateObject($this->item->expected_checkin, 'date', + false); + } + } + + /** + * Get the message envelope. + */ + public function envelope(): Envelope + { + $from = new Address(env('MAIL_FROM_ADDR', 'service@snipe-it.io')); + + return new Envelope( + from: $from, + subject: trans('mail.Asset_Checkout_Notification'), + ); + } + + /** + * Get the mail representation of the notification. + * + * @param mixed $notifiable + * @return Content + */ + public function content(): Content + { + $this->item->load('assetstatus'); + $eula = method_exists($this->item, 'getEula') ? $this->item->getEula() : ''; + $req_accept = method_exists($this->item, 'requireAcceptance') ? $this->item->requireAcceptance() : 0; + $fields = []; + + // Check if the item has custom fields associated with it + if (($this->item->model) && ($this->item->model->fieldset)) { + $fields = $this->item->model->fieldset->fields; + } + + $accept_url = is_null($this->acceptance) ? null : route('account.accept.item', $this->acceptance); + + return new Content( + markdown: 'mail.markdown.checkout-asset', + with: [ + 'item' => $this->item, + 'admin' => $this->admin, + 'status' => $this->item->assetstatus?->name, + 'note' => $this->note, + 'target' => $this->target, + 'fields' => $fields, + 'eula' => $eula, + 'req_accept' => $req_accept, + 'accept_url' => $accept_url, + 'last_checkout' => $this->last_checkout, + 'expected_checkin' => $this->expected_checkin, + ], + ); + } + + /** + * Get the attachments for the message. + * + * @return array + */ + public function attachments(): array + { + return []; + } +} diff --git a/app/Mail/CheckoutConsumableMail.php b/app/Mail/CheckoutConsumableMail.php new file mode 100644 index 0000000000..18fe228258 --- /dev/null +++ b/app/Mail/CheckoutConsumableMail.php @@ -0,0 +1,84 @@ +item = $consumable; + $this->admin = $checkedOutBy; + $this->note = $note; + $this->target = $checkedOutTo; + $this->acceptance = $acceptance; + $this->qty = $consumable->checkout_qty; + + $this->settings = Setting::getSettings(); + } + + /** + * Get the message envelope. + */ + public function envelope(): Envelope + { + $from = new Address(env('MAIL_FROM_ADDR','service@snipe-it.io')); + + return new Envelope( + from: $from, + subject: trans('mail.Confirm_consumable_delivery'), + ); + } + + /** + * Get the message content definition. + */ + public function content(): Content + { + + $eula = $this->item->getEula(); + $req_accept = $this->item->requireAcceptance(); + + $accept_url = is_null($this->acceptance) ? null : route('account.accept.item', $this->acceptance); + + return new Content( + markdown: 'mail.markdown.checkout-consumable', + with: [ + 'item' => $this->item, + 'admin' => $this->admin, + 'note' => $this->note, + 'target' => $this->target, + 'eula' => $eula, + 'req_accept' => $req_accept, + 'accept_url' => $accept_url, + 'qty' => $this->qty, + ] + ); + } + + /** + * Get the attachments for the message. + * + * @return array + */ + public function attachments(): array + { + return []; + } +} diff --git a/app/Mail/CheckoutLicenseMail.php b/app/Mail/CheckoutLicenseMail.php new file mode 100644 index 0000000000..ecd0d7390d --- /dev/null +++ b/app/Mail/CheckoutLicenseMail.php @@ -0,0 +1,80 @@ +item = $licenseSeat->license; + $this->admin = $checkedOutBy; + $this->note = $note; + $this->target = $checkedOutTo; + $this->acceptance = $acceptance; + + $this->settings = Setting::getSettings(); + } + + /** + * Get the message envelope. + */ + public function envelope(): Envelope + { + $from = new Address(env('MAIL_FROM_ADDR','service@snipe-it.io')); + + return new Envelope( + from: $from, + subject: trans('mail.Confirm_license_delivery'), + ); + } + + /** + * Get the message content definition. + */ + public function content(): Content + { + $eula = method_exists($this->item, 'getEula') ? $this->item->getEula() : ''; + $req_accept = method_exists($this->item, 'requireAcceptance') ? $this->item->requireAcceptance() : 0; + + $accept_url = is_null($this->acceptance) ? null : route('account.accept.item', $this->acceptance); + + return new Content( + markdown: 'mail.markdown.checkout-license', + with: [ + 'item' => $this->item, + 'admin' => $this->admin, + 'note' => $this->note, + 'target' => $this->target, + 'eula' => $eula, + 'req_accept' => $req_accept, + 'accept_url' => $accept_url, + ] + ); + } + + /** + * Get the attachments for the message. + * + * @return array + */ + public function attachments(): array + { + return []; + } +} diff --git a/app/Models/Recipients/AdminRecipient.php b/app/Models/Recipients/AdminRecipient.php index 433bd00209..90e39d4ee5 100644 --- a/app/Models/Recipients/AdminRecipient.php +++ b/app/Models/Recipients/AdminRecipient.php @@ -6,9 +6,15 @@ use App\Models\Setting; class AdminRecipient extends Recipient { + + protected $email; public function __construct() { $settings = Setting::getSettings(); $this->email = trim($settings->admin_cc_email); } + + public function getEmail(){ + return $this->email; + } } diff --git a/app/Notifications/CheckinAccessoryNotification.php b/app/Notifications/CheckinAccessoryNotification.php index 7e033f1870..d295515121 100644 --- a/app/Notifications/CheckinAccessoryNotification.php +++ b/app/Notifications/CheckinAccessoryNotification.php @@ -6,6 +6,7 @@ use App\Models\Accessory; use App\Models\Setting; use App\Models\User; use Illuminate\Bus\Queueable; +use Illuminate\Notifications\Channels\SlackWebhookChannel; use Illuminate\Notifications\Messages\MailMessage; use Illuminate\Notifications\Messages\SlackMessage; use Illuminate\Notifications\Notification; @@ -55,22 +56,9 @@ class CheckinAccessoryNotification extends Notification } if (Setting::getSettings()->webhook_selected == 'slack' || Setting::getSettings()->webhook_selected == 'general' ) { - $notifyBy[] = 'slack'; + $notifyBy[] = SlackWebhookChannel::class; } - /** - * Only send notifications to users that have email addresses - */ - if ($this->target instanceof User && $this->target->email != '') { - Log::debug('The target is a user'); - - if ($this->item->checkin_email()) { - $notifyBy[] = 'mail'; - } - } - - Log::debug('checkin_email on this category is '.$this->item->checkin_email()); - return $notifyBy; } @@ -142,24 +130,4 @@ class CheckinAccessoryNotification extends Notification ); } - - /** - * Get the mail representation of the notification. - * - * @param mixed $notifiable - * @return \Illuminate\Notifications\Messages\MailMessage - */ - public function toMail() - { - Log::debug('to email called'); - - return (new MailMessage)->markdown('notifications.markdown.checkin-accessory', - [ - 'item' => $this->item, - 'admin' => $this->admin, - 'note' => $this->note, - 'target' => $this->target, - ]) - ->subject(trans('mail.Accessory_Checkin_Notification')); - } } diff --git a/app/Notifications/CheckinAssetNotification.php b/app/Notifications/CheckinAssetNotification.php index 77cd6d9b5a..6f95437334 100644 --- a/app/Notifications/CheckinAssetNotification.php +++ b/app/Notifications/CheckinAssetNotification.php @@ -50,7 +50,6 @@ class CheckinAssetNotification extends Notification */ public function via() { - $notifyBy = []; if (Setting::getSettings()->webhook_selected == 'google' && Setting::getSettings()->webhook_endpoint) { $notifyBy[] = GoogleChatChannel::class; @@ -65,14 +64,6 @@ class CheckinAssetNotification extends Notification $notifyBy[] = 'slack'; } - /** - * Only send checkin notifications to users if the category - * has the corresponding checkbox checked. - */ - if ($this->item->checkin_email() && $this->target instanceof User && $this->target->email != '') { - $notifyBy[] = 'mail'; - } - return $notifyBy; } @@ -142,35 +133,5 @@ class CheckinAssetNotification extends Notification ) ) ); - - } - - /** - * Get the mail representation of the notification. - * - * @return \Illuminate\Notifications\Messages\MailMessage - */ - public function toMail() - { - $fields = []; - - // Check if the item has custom fields associated with it - if (($this->item->model) && ($this->item->model->fieldset)) { - $fields = $this->item->model->fieldset->fields; - } - - $message = (new MailMessage)->markdown('notifications.markdown.checkin-asset', - [ - 'item' => $this->item, - 'status' => $this->item->assetstatus?->name, - 'admin' => $this->admin, - 'note' => $this->note, - 'target' => $this->target, - 'fields' => $fields, - 'expected_checkin' => $this->expected_checkin, - ]) - ->subject(trans('mail.Asset_Checkin_Notification')); - - return $message; } } diff --git a/app/Notifications/CheckinLicenseSeatNotification.php b/app/Notifications/CheckinLicenseSeatNotification.php index 289e63a162..74018af7c9 100644 --- a/app/Notifications/CheckinLicenseSeatNotification.php +++ b/app/Notifications/CheckinLicenseSeatNotification.php @@ -6,6 +6,7 @@ use App\Models\LicenseSeat; use App\Models\Setting; use App\Models\User; use Illuminate\Bus\Queueable; +use Illuminate\Notifications\Channels\SlackWebhookChannel; use Illuminate\Notifications\Messages\MailMessage; use Illuminate\Notifications\Messages\SlackMessage; use Illuminate\Notifications\Notification; @@ -58,15 +59,7 @@ class CheckinLicenseSeatNotification extends Notification } if (Setting::getSettings()->webhook_selected == 'slack' || Setting::getSettings()->webhook_selected == 'general' ) { - $notifyBy[] = 'slack'; - } - - /** - * Only send checkin notifications to users if the category - * has the corresponding checkbox checked. - */ - if ($this->item->checkin_email() && $this->target instanceof User && $this->target->email != '') { - $notifyBy[] = 'mail'; + $notifyBy[] = SlackWebhookChannel::class; } return $notifyBy; @@ -149,23 +142,4 @@ class CheckinLicenseSeatNotification extends Notification ); } - - - /** - * Get the mail representation of the notification. - * - * @param mixed $notifiable - * @return \Illuminate\Notifications\Messages\MailMessage - */ - public function toMail() - { - return (new MailMessage)->markdown('notifications.markdown.checkin-license', - [ - 'item' => $this->item, - 'admin' => $this->admin, - 'note' => $this->note, - 'target' => $this->target, - ]) - ->subject(trans('mail.License_Checkin_Notification')); - } } diff --git a/app/Notifications/CheckoutAssetNotification.php b/app/Notifications/CheckoutAssetNotification.php index b14796fb8c..97706cec94 100644 --- a/app/Notifications/CheckoutAssetNotification.php +++ b/app/Notifications/CheckoutAssetNotification.php @@ -8,7 +8,7 @@ use App\Models\Setting; use App\Models\User; use Exception; use Illuminate\Bus\Queueable; -use Illuminate\Notifications\Messages\MailMessage; +use Illuminate\Notifications\Channels\SlackWebhookChannel; use Illuminate\Notifications\Messages\SlackMessage; use Illuminate\Notifications\Notification; use NotificationChannels\GoogleChat\Card; @@ -32,14 +32,11 @@ class CheckoutAssetNotification extends Notification */ public function __construct(Asset $asset, $checkedOutTo, User $checkedOutBy, $acceptance, $note) { + $this->settings = Setting::getSettings(); $this->item = $asset; $this->admin = $checkedOutBy; $this->note = $note; $this->target = $checkedOutTo; - $this->acceptance = $acceptance; - - $this->settings = Setting::getSettings(); - $this->last_checkout = ''; $this->expected_checkin = ''; @@ -53,7 +50,6 @@ class CheckoutAssetNotification extends Notification false); } } - /** * Get the notification's delivery channels. * @@ -62,61 +58,34 @@ class CheckoutAssetNotification extends Notification public function via() { $notifyBy = []; - if (Setting::getSettings()->webhook_selected == 'google' && Setting::getSettings()->webhook_endpoint) { + + if (Setting::getSettings()->webhook_selected === 'google' && Setting::getSettings()->webhook_endpoint) { $notifyBy[] = GoogleChatChannel::class; } - if (Setting::getSettings()->webhook_selected == 'microsoft' && Setting::getSettings()->webhook_endpoint) { + if (Setting::getSettings()->webhook_selected === 'microsoft' && Setting::getSettings()->webhook_endpoint) { $notifyBy[] = MicrosoftTeamsChannel::class; } - if (Setting::getSettings()->webhook_selected == 'slack' || Setting::getSettings()->webhook_selected == 'general' ) { + if (Setting::getSettings()->webhook_selected === 'slack' || Setting::getSettings()->webhook_selected === 'general' ) { Log::debug('use webhook'); - $notifyBy[] = 'slack'; - } - - /** - * Only send notifications to users that have email addresses - */ - if ($this->target instanceof User && $this->target->email != '') { - - /** - * Send an email if the asset requires acceptance, - * so the user can accept or decline the asset - */ - if ($this->item->requireAcceptance()) { - $notifyBy[1] = 'mail'; - } - - /** - * Send an email if the item has a EULA, since the user should always receive it - */ - if ($this->item->getEula()) { - $notifyBy[1] = 'mail'; - } - - /** - * Send an email if an email should be sent at checkin/checkout - */ - if ($this->item->checkin_email()) { - $notifyBy[1] = 'mail'; - } + $notifyBy[] = SlackWebhookChannel::class; } return $notifyBy; } - public function toSlack() + public function toSlack() :SlackMessage { $target = $this->target; $admin = $this->admin; $item = $this->item; $note = $this->note; - $botname = ($this->settings->webhook_botname) ? $this->settings->webhook_botname : 'Snipe-Bot'; + $botname = ($this->settings->webhook_botname) ?: 'Snipe-Bot'; $channel = ($this->settings->webhook_channel) ? $this->settings->webhook_channel : ''; $fields = [ @@ -124,7 +93,7 @@ class CheckoutAssetNotification extends Notification 'By' => '<'.$admin->present()->viewUrl().'|'.$admin->present()->fullName().'>', ]; - if (($this->expected_checkin) && ($this->expected_checkin != '')) { + if (($this->expected_checkin) && ($this->expected_checkin !== '')) { $fields['Expected Checkin'] = $this->expected_checkin; } @@ -184,42 +153,4 @@ public function toGoogleChat() ); } - - /** - * Get the mail representation of the notification. - * - * @param mixed $notifiable - * @return \Illuminate\Notifications\Messages\MailMessage - */ - public function toMail() - { $this->item->load('assetstatus'); - $eula = method_exists($this->item, 'getEula') ? $this->item->getEula() : ''; - $req_accept = method_exists($this->item, 'requireAcceptance') ? $this->item->requireAcceptance() : 0; - $fields = []; - - // Check if the item has custom fields associated with it - if (($this->item->model) && ($this->item->model->fieldset)) { - $fields = $this->item->model->fieldset->fields; - } - - $accept_url = is_null($this->acceptance) ? null : route('account.accept.item', $this->acceptance); - - $message = (new MailMessage)->markdown('notifications.markdown.checkout-asset', - [ - 'item' => $this->item, - 'admin' => $this->admin, - 'status' => $this->item->assetstatus?->name, - 'note' => $this->note, - 'target' => $this->target, - 'fields' => $fields, - 'eula' => $eula, - 'req_accept' => $req_accept, - 'accept_url' => $accept_url, - 'last_checkout' => $this->last_checkout, - 'expected_checkin' => $this->expected_checkin, - ]) - ->subject(trans('mail.Confirm_asset_delivery')); - - return $message; - } } diff --git a/app/Notifications/CheckoutConsumableNotification.php b/app/Notifications/CheckoutConsumableNotification.php index c974134fe6..e93d6e6ea6 100644 --- a/app/Notifications/CheckoutConsumableNotification.php +++ b/app/Notifications/CheckoutConsumableNotification.php @@ -6,6 +6,7 @@ use App\Models\Consumable; use App\Models\Setting; use App\Models\User; use Illuminate\Bus\Queueable; +use Illuminate\Notifications\Channels\SlackWebhookChannel; use Illuminate\Notifications\Messages\MailMessage; use Illuminate\Notifications\Messages\SlackMessage; use Illuminate\Notifications\Notification; @@ -62,35 +63,7 @@ class CheckoutConsumableNotification extends Notification } if (Setting::getSettings()->webhook_selected == 'slack' || Setting::getSettings()->webhook_selected == 'general' ) { - $notifyBy[] = 'slack'; - } - - /** - * Only send notifications to users that have email addresses - */ - if ($this->target instanceof User && $this->target->email != '') { - - /** - * Send an email if the asset requires acceptance, - * so the user can accept or decline the asset - */ - if ($this->item->requireAcceptance()) { - $notifyBy[1] = 'mail'; - } - - /** - * Send an email if the item has a EULA, since the user should always receive it - */ - if ($this->item->getEula()) { - $notifyBy[1] = 'mail'; - } - - /** - * Send an email if an email should be sent at checkin/checkout - */ - if ((method_exists($this->item, 'checkin_email')) && ($this->item->checkin_email())) { - $notifyBy[1] = 'mail'; - } + $notifyBy[] = SlackWebhookChannel::class; } return $notifyBy; @@ -166,30 +139,4 @@ class CheckoutConsumableNotification extends Notification ); } - - /** - * Get the mail representation of the notification. - * - * @return \Illuminate\Notifications\Messages\MailMessage - */ - public function toMail() - { - $eula = $this->item->getEula(); - $req_accept = $this->item->requireAcceptance(); - - $accept_url = is_null($this->acceptance) ? null : route('account.accept.item', $this->acceptance); - - return (new MailMessage)->markdown('notifications.markdown.checkout-consumable', - [ - 'item' => $this->item, - 'admin' => $this->admin, - 'note' => $this->note, - 'target' => $this->target, - 'eula' => $eula, - 'req_accept' => $req_accept, - 'accept_url' => $accept_url, - 'qty' => $this->qty, - ]) - ->subject(trans('mail.Confirm_consumable_delivery')); - } } diff --git a/app/Notifications/CheckoutLicenseSeatNotification.php b/app/Notifications/CheckoutLicenseSeatNotification.php index 8e0273c66e..1c26138a6e 100644 --- a/app/Notifications/CheckoutLicenseSeatNotification.php +++ b/app/Notifications/CheckoutLicenseSeatNotification.php @@ -6,6 +6,7 @@ use App\Models\LicenseSeat; use App\Models\Setting; use App\Models\User; use Illuminate\Bus\Queueable; +use Illuminate\Notifications\Channels\SlackWebhookChannel; use Illuminate\Notifications\Messages\MailMessage; use Illuminate\Notifications\Messages\SlackMessage; use Illuminate\Notifications\Notification; @@ -60,35 +61,7 @@ class CheckoutLicenseSeatNotification extends Notification } if (Setting::getSettings()->webhook_selected == 'slack' || Setting::getSettings()->webhook_selected == 'general' ) { - $notifyBy[] = 'slack'; - } - - /** - * Only send notifications to users that have email addresses - */ - if ($this->target instanceof User && $this->target->email != '') { - - /** - * Send an email if the asset requires acceptance, - * so the user can accept or decline the asset - */ - if ($this->item->requireAcceptance()) { - $notifyBy[1] = 'mail'; - } - - /** - * Send an email if the item has a EULA, since the user should always receive it - */ - if ($this->item->getEula()) { - $notifyBy[1] = 'mail'; - } - - /** - * Send an email if an email should be sent at checkin/checkout - */ - if ($this->item->checkin_email()) { - $notifyBy[1] = 'mail'; - } + $notifyBy[] = SlackWebhookChannel::class; } return $notifyBy; @@ -164,29 +137,4 @@ class CheckoutLicenseSeatNotification extends Notification ); } - - /** - * Get the mail representation of the notification. - * - * @return \Illuminate\Notifications\Messages\MailMessage - */ - public function toMail() - { - $eula = method_exists($this->item, 'getEula') ? $this->item->getEula() : ''; - $req_accept = method_exists($this->item, 'requireAcceptance') ? $this->item->requireAcceptance() : 0; - - $accept_url = is_null($this->acceptance) ? null : route('account.accept.item', $this->acceptance); - - return (new MailMessage)->markdown('notifications.markdown.checkout-license', - [ - 'item' => $this->item, - 'admin' => $this->admin, - 'note' => $this->note, - 'target' => $this->target, - 'eula' => $eula, - 'req_accept' => $req_accept, - 'accept_url' => $accept_url, - ]) - ->subject(trans('mail.Confirm_license_delivery')); - } } diff --git a/resources/views/notifications/markdown/checkin-accessory.blade.php b/resources/views/mail/markdown/checkin-accessory.blade.php similarity index 100% rename from resources/views/notifications/markdown/checkin-accessory.blade.php rename to resources/views/mail/markdown/checkin-accessory.blade.php diff --git a/resources/views/notifications/markdown/checkin-asset.blade.php b/resources/views/mail/markdown/checkin-asset.blade.php similarity index 100% rename from resources/views/notifications/markdown/checkin-asset.blade.php rename to resources/views/mail/markdown/checkin-asset.blade.php diff --git a/resources/views/notifications/markdown/checkin-license.blade.php b/resources/views/mail/markdown/checkin-license.blade.php similarity index 100% rename from resources/views/notifications/markdown/checkin-license.blade.php rename to resources/views/mail/markdown/checkin-license.blade.php diff --git a/resources/views/notifications/markdown/checkout-accessory.blade.php b/resources/views/mail/markdown/checkout-accessory.blade.php similarity index 100% rename from resources/views/notifications/markdown/checkout-accessory.blade.php rename to resources/views/mail/markdown/checkout-accessory.blade.php diff --git a/resources/views/notifications/markdown/checkout-asset.blade.php b/resources/views/mail/markdown/checkout-asset.blade.php similarity index 99% rename from resources/views/notifications/markdown/checkout-asset.blade.php rename to resources/views/mail/markdown/checkout-asset.blade.php index 9b5fc26dc2..aae0b21584 100644 --- a/resources/views/notifications/markdown/checkout-asset.blade.php +++ b/resources/views/mail/markdown/checkout-asset.blade.php @@ -73,4 +73,4 @@ {{ $snipeSettings->site_name }} -@endcomponent +@endcomponent \ No newline at end of file diff --git a/resources/views/notifications/markdown/checkout-consumable.blade.php b/resources/views/mail/markdown/checkout-consumable.blade.php similarity index 94% rename from resources/views/notifications/markdown/checkout-consumable.blade.php rename to resources/views/mail/markdown/checkout-consumable.blade.php index 92d516fd0a..0c8571acf5 100644 --- a/resources/views/notifications/markdown/checkout-consumable.blade.php +++ b/resources/views/mail/markdown/checkout-consumable.blade.php @@ -17,6 +17,9 @@ @if (isset($item->manufacturer)) | **{{ trans('general.manufacturer') }}** | {{ $item->manufacturer->name }} | @endif +@if (isset($qty)) +| **{{ trans('general.qty') }}** | {{ $qty }} | +@endif @if (isset($item->model_no)) | **{{ trans('general.model_no') }}** | {{ $item->model_no }} | @endif diff --git a/resources/views/notifications/markdown/checkout-license.blade.php b/resources/views/mail/markdown/checkout-license.blade.php similarity index 100% rename from resources/views/notifications/markdown/checkout-license.blade.php rename to resources/views/mail/markdown/checkout-license.blade.php diff --git a/routes/web.php b/routes/web.php index 60b74476c7..e54f4f706a 100644 --- a/routes/web.php +++ b/routes/web.php @@ -24,6 +24,8 @@ use App\Http\Controllers\Auth\LoginController; use App\Http\Controllers\Auth\ForgotPasswordController; use App\Http\Controllers\Auth\ResetPasswordController; use App\Livewire\Importer; +use App\Models\Asset; +use App\Models\User; use Illuminate\Support\Facades\Route; use Illuminate\Support\Facades\Auth; @@ -53,7 +55,6 @@ Route::group(['middleware' => 'auth'], function () { /* * Locations */ - Route::group(['prefix' => 'locations', 'middleware' => ['auth']], function () { Route::post( @@ -550,3 +551,22 @@ Route::middleware(['auth'])->get( '/', [DashboardController::class, 'index'] )->name('home'); +Route::get('/test-email', function() { + $item = Asset::find(1); // Load some test data + $admin = User::find(1); + $target = User::find(2); + $acceptance = null; // Simulate acceptance data + $note = 'Test note'; + + $fields = []; + if (($item->model) && ($item->model->fieldset)) { + $fields = $item->model->fieldset->fields; + } + + return new \App\Mail\CheckoutAssetMail( + $item, + $admin, + $target, + $acceptance, + $note); +}); \ No newline at end of file diff --git a/tests/Feature/Checkins/Ui/AccessoryCheckinTest.php b/tests/Feature/Checkins/Ui/AccessoryCheckinTest.php index 7a99b2ab56..dd5f944b82 100644 --- a/tests/Feature/Checkins/Ui/AccessoryCheckinTest.php +++ b/tests/Feature/Checkins/Ui/AccessoryCheckinTest.php @@ -3,10 +3,12 @@ namespace Tests\Feature\Checkins\Ui; use App\Events\CheckoutableCheckedIn; +use App\Mail\CheckinAccessoryMail; use App\Models\Accessory; use App\Models\User; use App\Notifications\CheckinAccessoryNotification; use Illuminate\Support\Facades\Event; +use Illuminate\Support\Facades\Mail; use Illuminate\Support\Facades\Notification; use Tests\TestCase; @@ -40,7 +42,7 @@ class AccessoryCheckinTest extends TestCase public function testEmailSentToUserIfSettingEnabled() { - Notification::fake(); + Mail::fake(); $user = User::factory()->create(); $accessory = Accessory::factory()->checkedOutToUser($user)->create(); @@ -53,23 +55,24 @@ class AccessoryCheckinTest extends TestCase User::factory()->checkinAccessories()->create(), '', )); + Mail::assertSent(CheckinAccessoryMail::class, function (CheckinAccessoryMail $mail) use ( $accessory, $user) { + return $mail->hasTo($user->email); - Notification::assertSentTo( - [$user], - function (CheckinAccessoryNotification $notification, $channels) { - return in_array('mail', $channels); - }, - ); + }); } public function testEmailNotSentToUserIfSettingDisabled() { - Notification::fake(); + Mail::fake(); $user = User::factory()->create(); $accessory = Accessory::factory()->checkedOutToUser($user)->create(); - $accessory->category->update(['checkin_email' => false]); + $accessory->category->update([ + 'checkin_email' => false, + 'require_acceptance' => false, + 'eula_text' => null + ]); event(new CheckoutableCheckedIn( $accessory, @@ -78,11 +81,8 @@ class AccessoryCheckinTest extends TestCase '', )); - Notification::assertNotSentTo( - [$user], - function (CheckinAccessoryNotification $notification, $channels) { - return in_array('mail', $channels); - }, - ); + Mail::assertNotSent(CheckinAccessoryMail::class, function ($mail) use ($user) { + return $mail->hasTo($user->email); + }); } } diff --git a/tests/Feature/Checkouts/Api/AccessoryCheckoutTest.php b/tests/Feature/Checkouts/Api/AccessoryCheckoutTest.php index 765b8436a0..7adab09c03 100644 --- a/tests/Feature/Checkouts/Api/AccessoryCheckoutTest.php +++ b/tests/Feature/Checkouts/Api/AccessoryCheckoutTest.php @@ -2,10 +2,12 @@ namespace Tests\Feature\Checkouts\Api; +use App\Mail\CheckoutAccessoryMail; use App\Models\Accessory; use App\Models\Actionlog; use App\Models\User; use App\Notifications\CheckoutAccessoryNotification; +use Illuminate\Support\Facades\Mail; use Illuminate\Support\Facades\Notification; use Tests\Concerns\TestsPermissionsRequirement; use Tests\TestCase; @@ -146,7 +148,7 @@ class AccessoryCheckoutTest extends TestCase implements TestsPermissionsRequirem public function testUserSentNotificationUponCheckout() { - Notification::fake(); + Mail::fake(); $accessory = Accessory::factory()->requiringAcceptance()->create(); $user = User::factory()->create(); @@ -157,7 +159,9 @@ class AccessoryCheckoutTest extends TestCase implements TestsPermissionsRequirem 'checkout_to_type' => 'user', ]); - Notification::assertSentTo($user, CheckoutAccessoryNotification::class); + Mail::assertSent(CheckoutAccessoryMail::class, function ($mail) use ($user) { + return $mail->hasTo($user->email); + }); } public function testActionLogCreatedUponCheckout() diff --git a/tests/Feature/Checkouts/Api/ConsumableCheckoutTest.php b/tests/Feature/Checkouts/Api/ConsumableCheckoutTest.php index 94fa63cba3..fba2c50df3 100644 --- a/tests/Feature/Checkouts/Api/ConsumableCheckoutTest.php +++ b/tests/Feature/Checkouts/Api/ConsumableCheckoutTest.php @@ -2,10 +2,12 @@ namespace Tests\Feature\Checkouts\Api; +use App\Mail\CheckoutConsumableMail; use App\Models\Actionlog; use App\Models\Consumable; use App\Models\User; use App\Notifications\CheckoutConsumableNotification; +use Illuminate\Support\Facades\Mail; use Illuminate\Support\Facades\Notification; use Tests\TestCase; @@ -51,7 +53,7 @@ class ConsumableCheckoutTest extends TestCase public function testUserSentNotificationUponCheckout() { - Notification::fake(); + Mail::fake(); $consumable = Consumable::factory()->requiringAcceptance()->create(); @@ -62,7 +64,9 @@ class ConsumableCheckoutTest extends TestCase 'assigned_to' => $user->id, ]); - Notification::assertSentTo($user, CheckoutConsumableNotification::class); + Mail::assertSent(CheckoutConsumableMail::class, function ($mail) use ($consumable, $user) { + return $mail->hasTo($user->email); + }); } public function testActionLogCreatedUponCheckout() diff --git a/tests/Feature/Checkouts/Ui/AccessoryCheckoutTest.php b/tests/Feature/Checkouts/Ui/AccessoryCheckoutTest.php index f63a8471f2..af9b286725 100644 --- a/tests/Feature/Checkouts/Ui/AccessoryCheckoutTest.php +++ b/tests/Feature/Checkouts/Ui/AccessoryCheckoutTest.php @@ -2,12 +2,14 @@ namespace Tests\Feature\Checkouts\Ui; +use App\Mail\CheckoutAccessoryMail; use App\Models\Accessory; use App\Models\Actionlog; use App\Models\Asset; use App\Models\Location; use App\Models\User; use App\Notifications\CheckoutAccessoryNotification; +use Illuminate\Support\Facades\Mail; use Illuminate\Support\Facades\Notification; use Tests\TestCase; @@ -156,7 +158,7 @@ class AccessoryCheckoutTest extends TestCase public function testUserSentNotificationUponCheckout() { - Notification::fake(); + Mail::fake(); $accessory = Accessory::factory()->requiringAcceptance()->create(); $user = User::factory()->create(); @@ -168,7 +170,9 @@ class AccessoryCheckoutTest extends TestCase 'checkout_to_type' => 'user', ]); - Notification::assertSentTo($user, CheckoutAccessoryNotification::class); + Mail::assertSent(CheckoutAccessoryMail::class, function ($mail) use ($user) { + return $mail->hasTo($user->email); + }); } public function testActionLogCreatedUponCheckout() diff --git a/tests/Feature/Checkouts/Ui/ConsumableCheckoutTest.php b/tests/Feature/Checkouts/Ui/ConsumableCheckoutTest.php index 484b7e72cb..2dc5fa62c0 100644 --- a/tests/Feature/Checkouts/Ui/ConsumableCheckoutTest.php +++ b/tests/Feature/Checkouts/Ui/ConsumableCheckoutTest.php @@ -2,12 +2,14 @@ namespace Tests\Feature\Checkouts\Ui; +use App\Mail\CheckoutConsumableMail; use App\Models\Actionlog; use App\Models\Asset; use App\Models\Component; use App\Models\Consumable; use App\Models\User; use App\Notifications\CheckoutConsumableNotification; +use Illuminate\Support\Facades\Mail; use Illuminate\Support\Facades\Notification; use Tests\TestCase; @@ -53,7 +55,7 @@ class ConsumableCheckoutTest extends TestCase public function testUserSentNotificationUponCheckout() { - Notification::fake(); + Mail::fake(); $consumable = Consumable::factory()->create(); $user = User::factory()->create(); @@ -63,7 +65,9 @@ class ConsumableCheckoutTest extends TestCase 'assigned_to' => $user->id, ]); - Notification::assertSentTo($user, CheckoutConsumableNotification::class); + Mail::assertSent(CheckoutConsumableMail::class, function ($mail) use ($user) { + return $mail->hasTo($user->email); + }); } public function testActionLogCreatedUponCheckout() diff --git a/tests/Feature/Importing/Api/ImportAssetsTest.php b/tests/Feature/Importing/Api/ImportAssetsTest.php index e001add381..0f54b22e92 100644 --- a/tests/Feature/Importing/Api/ImportAssetsTest.php +++ b/tests/Feature/Importing/Api/ImportAssetsTest.php @@ -2,6 +2,7 @@ namespace Tests\Feature\Importing\Api; +use App\Mail\CheckoutAssetMail; use App\Models\Actionlog as ActionLog; use App\Models\Asset; use App\Models\CustomField; @@ -11,6 +12,7 @@ use App\Notifications\CheckoutAssetNotification; use Carbon\Carbon; use Illuminate\Foundation\Testing\WithFaker; use Illuminate\Support\Arr; +use Illuminate\Support\Facades\Mail; use Illuminate\Support\Facades\Notification; use Illuminate\Support\Str; use Illuminate\Testing\TestResponse; @@ -54,7 +56,6 @@ class ImportAssetsTest extends ImportDataTestCase implements TestsPermissionsReq #[Test] public function importAsset(): void { - Notification::fake(); $importFileBuilder = ImportFileBuilder::new(); $row = $importFileBuilder->firstRow(); @@ -138,7 +139,6 @@ class ImportAssetsTest extends ImportDataTestCase implements TestsPermissionsReq //Notes is never read. // $this->assertEquals($row['notes'], $newAsset->notes); - Notification::assertSentTo($assignee, CheckoutAssetNotification::class); } #[Test] diff --git a/tests/Feature/Notifications/Email/EmailNotificationsUponCheckinTest.php b/tests/Feature/Notifications/Email/EmailNotificationsUponCheckinTest.php index 449f65c7ab..b4f360cfc3 100644 --- a/tests/Feature/Notifications/Email/EmailNotificationsUponCheckinTest.php +++ b/tests/Feature/Notifications/Email/EmailNotificationsUponCheckinTest.php @@ -2,6 +2,8 @@ namespace Tests\Feature\Notifications\Email; +use App\Mail\CheckinAssetMail; +use Illuminate\Support\Facades\Mail; use PHPUnit\Framework\Attributes\Group; use App\Events\CheckoutableCheckedIn; use App\Models\Asset; @@ -17,11 +19,13 @@ class EmailNotificationsUponCheckinTest extends TestCase { parent::setUp(); - Notification::fake(); + Mail::fake(); } public function testCheckInEmailSentToUserIfSettingEnabled() { + Mail::fake(); + $user = User::factory()->create(); $asset = Asset::factory()->assignedToUser($user)->create(); @@ -29,27 +33,29 @@ class EmailNotificationsUponCheckinTest extends TestCase $this->fireCheckInEvent($asset, $user); - Notification::assertSentTo( - $user, - function (CheckinAssetNotification $notification, $channels) { - return in_array('mail', $channels); - }, - ); + Mail::assertSent(CheckinAssetMail::class, function($mail) use ($user) { + return $mail->hasTo($user->email); + }); + } public function testCheckInEmailNotSentToUserIfSettingDisabled() { + Mail::fake(); + $user = User::factory()->create(); $asset = Asset::factory()->assignedToUser($user)->create(); - $asset->model->category->update(['checkin_email' => false]); + $asset->model->category->update([ + 'checkin_email' => false, + 'eula_text' => null, + 'require_acceptance' => false, + ]); $this->fireCheckInEvent($asset, $user); - Notification::assertNotSentTo( - $user, - function (CheckinAssetNotification $notification, $channels) { - return in_array('mail', $channels); + Mail::assertNotSent(CheckinAssetMail::class, function($mail) use ($user) { + return $mail->hasTo($user->email); } ); } diff --git a/tests/Unit/NotificationTest.php b/tests/Unit/NotificationTest.php index 86177c3030..3d5b3c5a76 100644 --- a/tests/Unit/NotificationTest.php +++ b/tests/Unit/NotificationTest.php @@ -1,12 +1,14 @@ Carbon::createFromDate(2017, 1, 1)->hour(0)->minute(0)->second(0)->format('Y-m-d') ]); - Notification::fake(); + Mail::fake(); $asset->checkOut($user, $admin->id); - Notification::assertSentTo($user, CheckoutAssetNotification::class); + Mail::assertSent(CheckoutAssetMail::class, function ($mail) use ($user) { + return $mail->hasTo($user->email); + }); } public function testDefaultEulaIsSentWhenSetInCategory() { - Notification::fake(); + Mail::fake(); $this->settings->setEula('My Custom EULA Text'); @@ -51,10 +55,10 @@ class NotificationTest extends TestCase $asset->checkOut($user, User::factory()->superuser()->create()->id); - Notification::assertSentTo($user, CheckoutAssetNotification::class, function ($notification) { - $content = $notification->toMail()->render(); - - return str_contains($content, 'My Custom EULA Text') && !str_contains($content, 'EULA Text that should not be used'); + Mail::assertSent(CheckoutAssetMail::class, function ($mail) use ($user) { + return $mail->hasTo($user->email) && + str_contains($mail->render(), 'My Custom EULA Text') && + !str_contains($mail->render(), 'EULA Text that should not be used'); }); } }