From fdcb891cbbdb42e8999cb27e1dcaa960ded995ba Mon Sep 17 00:00:00 2001 From: Marcus Moore Date: Wed, 29 Jan 2025 15:20:56 -0800 Subject: [PATCH 01/15] Improve test case --- tests/Unit/NotificationTest.php | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/tests/Unit/NotificationTest.php b/tests/Unit/NotificationTest.php index 3d5b3c5a7651..5b420a675385 100644 --- a/tests/Unit/NotificationTest.php +++ b/tests/Unit/NotificationTest.php @@ -7,9 +7,7 @@ use App\Models\AssetModel; use App\Models\Category; use Carbon\Carbon; -use App\Notifications\CheckoutAssetNotification; use Illuminate\Support\Facades\Mail; -use Illuminate\Support\Facades\Notification; use Tests\TestCase; class NotificationTest extends TestCase @@ -33,8 +31,8 @@ public function testAUserIsEmailedIfTheyCheckoutAnAssetWithEULA() Mail::fake(); $asset->checkOut($user, $admin->id); - Mail::assertSent(CheckoutAssetMail::class, function ($mail) use ($user) { - return $mail->hasTo($user->email); + Mail::assertSent(CheckoutAssetMail::class, function (CheckoutAssetMail $mail) use ($user) { + return $mail->hasTo($user->email) && $mail->hasSubject(trans('mail.Asset_Checkout_Notification')); }); } public function testDefaultEulaIsSentWhenSetInCategory() From d254a40e0a90ef080b74fb39745c5b24d0993a33 Mon Sep 17 00:00:00 2001 From: Marcus Moore Date: Wed, 29 Jan 2025 15:21:10 -0800 Subject: [PATCH 02/15] Scaffold tests --- .../factories/CheckoutAcceptanceFactory.php | 19 ++++ .../Email/AssetAcceptanceReminderTest.php | 90 +++++++++++++++++++ 2 files changed, 109 insertions(+) create mode 100644 tests/Feature/Notifications/Email/AssetAcceptanceReminderTest.php diff --git a/database/factories/CheckoutAcceptanceFactory.php b/database/factories/CheckoutAcceptanceFactory.php index 6bb87d18e11d..8dbb6712c6fb 100644 --- a/database/factories/CheckoutAcceptanceFactory.php +++ b/database/factories/CheckoutAcceptanceFactory.php @@ -27,6 +27,17 @@ public function definition() public function configure(): static { return $this->afterCreating(function (CheckoutAcceptance $acceptance) { + // @todo: add comment + if ($acceptance->checkoutable instanceof Asset) { + $acceptance->checkoutable->assetlog()->create([ + 'action_type' => 'checkout', + 'target_id' => $acceptance->assigned_to_id, + 'target_type' => get_class($acceptance->assignedTo), + 'item_id' => $acceptance->checkoutable_id, + 'item_type' => $acceptance->checkoutable_type, + ]); + } + if ($acceptance->checkoutable instanceof Asset && $acceptance->assignedTo instanceof User) { $acceptance->checkoutable->update([ 'assigned_to' => $acceptance->assigned_to_id, @@ -51,4 +62,12 @@ public function pending() 'declined_at' => null, ]); } + + public function accepted() + { + return $this->state([ + 'accepted_at' => now()->subDay(), + 'declined_at' => null, + ]); + } } diff --git a/tests/Feature/Notifications/Email/AssetAcceptanceReminderTest.php b/tests/Feature/Notifications/Email/AssetAcceptanceReminderTest.php new file mode 100644 index 000000000000..3809b826e6a4 --- /dev/null +++ b/tests/Feature/Notifications/Email/AssetAcceptanceReminderTest.php @@ -0,0 +1,90 @@ +actor = User::factory()->canViewReports()->create(); + $this->checkoutAcceptance = CheckoutAcceptance::factory()->pending()->create(); + } + + public function testMustHavePermissionToSendReminder() + { + $userWithoutPermission = User::factory()->create(); + + $this->actingAs($userWithoutPermission) + ->post($this->routeFor($this->checkoutAcceptance)) + ->assertForbidden(); + } + + public function testReminderNotSentIfAcceptanceDoesNotExist() + { + $this->actingAs($this->actor) + ->post(route('reports/unaccepted_assets_sent_reminder', [ + 'acceptance_id' => 999999, + ])); + + Mail::assertNotSent(CheckoutAssetMail::class); + } + + public function testReminderNotSentIfAcceptanceAlreadyAccepted() + { + $checkoutAcceptanceAlreadyAccepted = CheckoutAcceptance::factory()->accepted()->create(); + + $this->actingAs($this->actor) + ->post($this->routeFor($checkoutAcceptanceAlreadyAccepted)); + + Mail::assertNotSent(CheckoutAssetMail::class); + } + + public function testUserWithoutEmailAddressHandledGracefully() + { + $userWithoutEmailAddress = User::factory()->create(['email' => null]); + + $this->checkoutAcceptance->assigned_to_id = $userWithoutEmailAddress->id; + $this->checkoutAcceptance->save(); + + $this->actingAs($this->actor) + ->post($this->routeFor($this->checkoutAcceptance)) + // check we didn't crash... + ->assertRedirect(); + + Mail::assertNotSent(CheckoutAssetMail::class); + } + + public function testReminderIsSentToUser() + { + $this->actingAs($this->actor) + ->post($this->routeFor($this->checkoutAcceptance)) + ->assertRedirect(route('reports/unaccepted_assets')); + + Mail::assertSent(CheckoutAssetMail::class, 1); + Mail::assertSent(CheckoutAssetMail::class, function (CheckoutAssetMail $mail) { + return $mail->hasTo($this->checkoutAcceptance->assignedTo->email) + // @todo: + && $mail->hasSubject('Reminder: ' . trans('mail.Asset_Checkout_Notification')); + }); + } + + private function routeFor(CheckoutAcceptance $checkoutAcceptance): string + { + return route('reports/unaccepted_assets_sent_reminder', [ + 'acceptance_id' => $checkoutAcceptance->id, + ]); + } +} From e2805f40332afce449c72695c0f4fbca232d718e Mon Sep 17 00:00:00 2001 From: Marcus Moore Date: Wed, 29 Jan 2025 15:36:45 -0800 Subject: [PATCH 03/15] Add "Reminder" to subject line --- app/Http/Controllers/ReportsController.php | 5 ++- app/Mail/CheckoutAssetMail.php | 15 +++++++-- .../Email/AssetAcceptanceReminderTest.php | 31 ++++++++++++++++--- 3 files changed, 41 insertions(+), 10 deletions(-) diff --git a/app/Http/Controllers/ReportsController.php b/app/Http/Controllers/ReportsController.php index f0bbfb74a26a..33188d0c0158 100644 --- a/app/Http/Controllers/ReportsController.php +++ b/app/Http/Controllers/ReportsController.php @@ -1177,10 +1177,9 @@ public function sentAssetAcceptanceReminder(Request $request) : RedirectResponse $locale = $assetItem->assignedTo?->locale; // Only send notification if assigned if ($locale && $email) { - Mail::to($email)->send((new CheckoutAssetMail($assetItem, $assetItem->assignedTo, $logItem->user, $acceptance, $logItem->note))->locale($locale)); - + Mail::to($email)->send((new CheckoutAssetMail($assetItem, $assetItem->assignedTo, $logItem->user, $acceptance, $logItem->note, firstTimeSending: false))->locale($locale)); } elseif ($email) { - Mail::to($email)->send((new CheckoutAssetMail($assetItem, $assetItem->assignedTo, $logItem->user, $acceptance, $logItem->note))); + Mail::to($email)->send((new CheckoutAssetMail($assetItem, $assetItem->assignedTo, $logItem->user, $acceptance, $logItem->note, firstTimeSending: false))); } if ($email == ''){ diff --git a/app/Mail/CheckoutAssetMail.php b/app/Mail/CheckoutAssetMail.php index 680014dcd189..fbdaa4fcc0b4 100644 --- a/app/Mail/CheckoutAssetMail.php +++ b/app/Mail/CheckoutAssetMail.php @@ -20,10 +20,12 @@ class CheckoutAssetMail extends Mailable { use Queueable, SerializesModels; + private bool $firstTimeSending; + /** * Create a new message instance. */ - public function __construct(Asset $asset, $checkedOutTo, User $checkedOutBy, $acceptance, $note) + public function __construct(Asset $asset, $checkedOutTo, User $checkedOutBy, $acceptance, $note, bool $firstTimeSending = true) { $this->item = $asset; $this->admin = $checkedOutBy; @@ -36,6 +38,8 @@ public function __construct(Asset $asset, $checkedOutTo, User $checkedOutBy, $a $this->last_checkout = ''; $this->expected_checkin = ''; + $this->firstTimeSending = $firstTimeSending; + if ($this->item->last_checkout) { $this->last_checkout = Helper::getFormattedDateObject($this->item->last_checkout, 'date', false); @@ -54,9 +58,16 @@ public function envelope(): Envelope { $from = new Address(config('mail.from.address'), config('mail.from.name')); + $subject = trans('mail.Asset_Checkout_Notification'); + + if (!$this->firstTimeSending) { + // @todo: translate + $subject = 'Reminder: ' . $subject; + } + return new Envelope( from: $from, - subject: trans('mail.Asset_Checkout_Notification'), + subject: $subject, ); } diff --git a/tests/Feature/Notifications/Email/AssetAcceptanceReminderTest.php b/tests/Feature/Notifications/Email/AssetAcceptanceReminderTest.php index 3809b826e6a4..d84b2f712045 100644 --- a/tests/Feature/Notifications/Email/AssetAcceptanceReminderTest.php +++ b/tests/Feature/Notifications/Email/AssetAcceptanceReminderTest.php @@ -6,6 +6,7 @@ use App\Models\CheckoutAcceptance; use App\Models\User; use Illuminate\Support\Facades\Mail; +use PHPUnit\Framework\Attributes\DataProvider; use Tests\TestCase; class AssetAcceptanceReminderTest extends TestCase @@ -67,16 +68,36 @@ public function testUserWithoutEmailAddressHandledGracefully() Mail::assertNotSent(CheckoutAssetMail::class); } - public function testReminderIsSentToUser() + public static function users() { + yield 'User with locale set' => [ + function () { + return CheckoutAcceptance::factory()->pending()->create(); + } + ]; + + yield 'User without locale set' => [ + function () { + $checkoutAcceptance = CheckoutAcceptance::factory()->pending()->create(); + $checkoutAcceptance->assignedTo->update(['locale' => null]); + + return $checkoutAcceptance; + } + ]; + } + + #[DataProvider('users')] + public function testReminderIsSentToUser($data) + { + $checkoutAcceptance = $data(); + $this->actingAs($this->actor) - ->post($this->routeFor($this->checkoutAcceptance)) + ->post($this->routeFor($checkoutAcceptance)) ->assertRedirect(route('reports/unaccepted_assets')); Mail::assertSent(CheckoutAssetMail::class, 1); - Mail::assertSent(CheckoutAssetMail::class, function (CheckoutAssetMail $mail) { - return $mail->hasTo($this->checkoutAcceptance->assignedTo->email) - // @todo: + Mail::assertSent(CheckoutAssetMail::class, function (CheckoutAssetMail $mail) use ($checkoutAcceptance) { + return $mail->hasTo($checkoutAcceptance->assignedTo->email) && $mail->hasSubject('Reminder: ' . trans('mail.Asset_Checkout_Notification')); }); } From 70aed45bfe6c5d4b5ee4ed964c58b414d2d35718 Mon Sep 17 00:00:00 2001 From: Marcus Moore Date: Wed, 29 Jan 2025 15:56:20 -0800 Subject: [PATCH 04/15] Improve naming --- .../Notifications/Email/AssetAcceptanceReminderTest.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/Feature/Notifications/Email/AssetAcceptanceReminderTest.php b/tests/Feature/Notifications/Email/AssetAcceptanceReminderTest.php index d84b2f712045..7411cfbd3b97 100644 --- a/tests/Feature/Notifications/Email/AssetAcceptanceReminderTest.php +++ b/tests/Feature/Notifications/Email/AssetAcceptanceReminderTest.php @@ -68,7 +68,7 @@ public function testUserWithoutEmailAddressHandledGracefully() Mail::assertNotSent(CheckoutAssetMail::class); } - public static function users() + public static function acceptances() { yield 'User with locale set' => [ function () { @@ -86,10 +86,10 @@ function () { ]; } - #[DataProvider('users')] - public function testReminderIsSentToUser($data) + #[DataProvider('acceptances')] + public function testReminderIsSentToUser($callback) { - $checkoutAcceptance = $data(); + $checkoutAcceptance = $callback(); $this->actingAs($this->actor) ->post($this->routeFor($checkoutAcceptance)) From 4e7c6bd2cfd87901fec2c71cde855f4c63f77c0c Mon Sep 17 00:00:00 2001 From: Marcus Moore Date: Wed, 29 Jan 2025 16:14:09 -0800 Subject: [PATCH 05/15] Fix relationship --- .../Email/AssetAcceptanceReminderTest.php | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/tests/Feature/Notifications/Email/AssetAcceptanceReminderTest.php b/tests/Feature/Notifications/Email/AssetAcceptanceReminderTest.php index 7411cfbd3b97..4898234e108a 100644 --- a/tests/Feature/Notifications/Email/AssetAcceptanceReminderTest.php +++ b/tests/Feature/Notifications/Email/AssetAcceptanceReminderTest.php @@ -55,13 +55,13 @@ public function testReminderNotSentIfAcceptanceAlreadyAccepted() public function testUserWithoutEmailAddressHandledGracefully() { - $userWithoutEmailAddress = User::factory()->create(['email' => null]); - - $this->checkoutAcceptance->assigned_to_id = $userWithoutEmailAddress->id; - $this->checkoutAcceptance->save(); + $checkoutAcceptance = CheckoutAcceptance::factory() + ->pending() + ->forAssignedTo(['email' => null]) + ->create(); $this->actingAs($this->actor) - ->post($this->routeFor($this->checkoutAcceptance)) + ->post($this->routeFor($checkoutAcceptance)) // check we didn't crash... ->assertRedirect(); From 78f92925553d29c6149fcd7c45b1a75dd03b1b17 Mon Sep 17 00:00:00 2001 From: Marcus Moore Date: Wed, 29 Jan 2025 16:15:27 -0800 Subject: [PATCH 06/15] Inline variable --- .../Notifications/Email/AssetAcceptanceReminderTest.php | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/tests/Feature/Notifications/Email/AssetAcceptanceReminderTest.php b/tests/Feature/Notifications/Email/AssetAcceptanceReminderTest.php index 4898234e108a..34bc935bb751 100644 --- a/tests/Feature/Notifications/Email/AssetAcceptanceReminderTest.php +++ b/tests/Feature/Notifications/Email/AssetAcceptanceReminderTest.php @@ -11,7 +11,6 @@ class AssetAcceptanceReminderTest extends TestCase { - private CheckoutAcceptance $checkoutAcceptance; private User $actor; protected function setUp(): void @@ -21,15 +20,15 @@ protected function setUp(): void Mail::fake(); $this->actor = User::factory()->canViewReports()->create(); - $this->checkoutAcceptance = CheckoutAcceptance::factory()->pending()->create(); } public function testMustHavePermissionToSendReminder() { + $checkoutAcceptance = CheckoutAcceptance::factory()->pending()->create(); $userWithoutPermission = User::factory()->create(); $this->actingAs($userWithoutPermission) - ->post($this->routeFor($this->checkoutAcceptance)) + ->post($this->routeFor($checkoutAcceptance)) ->assertForbidden(); } From ce31ce477e046ecec0cc6d56a5df7c44ab863c87 Mon Sep 17 00:00:00 2001 From: Marcus Moore Date: Wed, 29 Jan 2025 16:16:47 -0800 Subject: [PATCH 07/15] Inline additional variables --- .../Email/AssetAcceptanceReminderTest.php | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/tests/Feature/Notifications/Email/AssetAcceptanceReminderTest.php b/tests/Feature/Notifications/Email/AssetAcceptanceReminderTest.php index 34bc935bb751..f163225d1bfb 100644 --- a/tests/Feature/Notifications/Email/AssetAcceptanceReminderTest.php +++ b/tests/Feature/Notifications/Email/AssetAcceptanceReminderTest.php @@ -11,15 +11,11 @@ class AssetAcceptanceReminderTest extends TestCase { - private User $actor; - protected function setUp(): void { parent::setUp(); Mail::fake(); - - $this->actor = User::factory()->canViewReports()->create(); } public function testMustHavePermissionToSendReminder() @@ -34,7 +30,7 @@ public function testMustHavePermissionToSendReminder() public function testReminderNotSentIfAcceptanceDoesNotExist() { - $this->actingAs($this->actor) + $this->actingAs(User::factory()->canViewReports()->create()) ->post(route('reports/unaccepted_assets_sent_reminder', [ 'acceptance_id' => 999999, ])); @@ -46,7 +42,7 @@ public function testReminderNotSentIfAcceptanceAlreadyAccepted() { $checkoutAcceptanceAlreadyAccepted = CheckoutAcceptance::factory()->accepted()->create(); - $this->actingAs($this->actor) + $this->actingAs(User::factory()->canViewReports()->create()) ->post($this->routeFor($checkoutAcceptanceAlreadyAccepted)); Mail::assertNotSent(CheckoutAssetMail::class); @@ -59,7 +55,7 @@ public function testUserWithoutEmailAddressHandledGracefully() ->forAssignedTo(['email' => null]) ->create(); - $this->actingAs($this->actor) + $this->actingAs(User::factory()->canViewReports()->create()) ->post($this->routeFor($checkoutAcceptance)) // check we didn't crash... ->assertRedirect(); @@ -90,7 +86,7 @@ public function testReminderIsSentToUser($callback) { $checkoutAcceptance = $callback(); - $this->actingAs($this->actor) + $this->actingAs(User::factory()->canViewReports()->create()) ->post($this->routeFor($checkoutAcceptance)) ->assertRedirect(route('reports/unaccepted_assets')); From d1197d015c22758bbc49f9f6046f76db9e95a844 Mon Sep 17 00:00:00 2001 From: Marcus Moore Date: Wed, 29 Jan 2025 16:24:43 -0800 Subject: [PATCH 08/15] Add another case scenario --- .../Email/AssetAcceptanceReminderTest.php | 29 +++++++++++++++---- 1 file changed, 24 insertions(+), 5 deletions(-) diff --git a/tests/Feature/Notifications/Email/AssetAcceptanceReminderTest.php b/tests/Feature/Notifications/Email/AssetAcceptanceReminderTest.php index f163225d1bfb..d7c89e041e2e 100644 --- a/tests/Feature/Notifications/Email/AssetAcceptanceReminderTest.php +++ b/tests/Feature/Notifications/Email/AssetAcceptanceReminderTest.php @@ -48,12 +48,31 @@ public function testReminderNotSentIfAcceptanceAlreadyAccepted() Mail::assertNotSent(CheckoutAssetMail::class); } - public function testUserWithoutEmailAddressHandledGracefully() + public static function CheckoutAcceptancesToUsersWithoutEmailAddresses() { - $checkoutAcceptance = CheckoutAcceptance::factory() - ->pending() - ->forAssignedTo(['email' => null]) - ->create(); + yield 'User with null email address' => [ + function () { + return CheckoutAcceptance::factory() + ->pending() + ->forAssignedTo(['email' => null]) + ->create(); + } + ]; + + yield 'User with empty string email address' => [ + function () { + return CheckoutAcceptance::factory() + ->pending() + ->forAssignedTo(['email' => '']) + ->create(); + } + ]; + } + + #[DataProvider('CheckoutAcceptancesToUsersWithoutEmailAddresses')] + public function testUserWithoutEmailAddressHandledGracefully($callback) + { + $checkoutAcceptance = $callback(); $this->actingAs(User::factory()->canViewReports()->create()) ->post($this->routeFor($checkoutAcceptance)) From c15c338ffd29beed180d352897599226f70d10bb Mon Sep 17 00:00:00 2001 From: Marcus Moore Date: Wed, 29 Jan 2025 16:25:37 -0800 Subject: [PATCH 09/15] Merge if/else --- app/Http/Controllers/ReportsController.php | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/app/Http/Controllers/ReportsController.php b/app/Http/Controllers/ReportsController.php index 33188d0c0158..5ce23138e2b1 100644 --- a/app/Http/Controllers/ReportsController.php +++ b/app/Http/Controllers/ReportsController.php @@ -1176,11 +1176,9 @@ public function sentAssetAcceptanceReminder(Request $request) : RedirectResponse $email = $assetItem->assignedTo?->email; $locale = $assetItem->assignedTo?->locale; // Only send notification if assigned - if ($locale && $email) { + if ($email) { Mail::to($email)->send((new CheckoutAssetMail($assetItem, $assetItem->assignedTo, $logItem->user, $acceptance, $logItem->note, firstTimeSending: false))->locale($locale)); - } elseif ($email) { - Mail::to($email)->send((new CheckoutAssetMail($assetItem, $assetItem->assignedTo, $logItem->user, $acceptance, $logItem->note, firstTimeSending: false))); - } + } if ($email == ''){ return redirect()->route('reports/unaccepted_assets')->with('error', trans('general.no_email')); From ab9e9b66d257d91ca35351ee423901223d7afc1b Mon Sep 17 00:00:00 2001 From: Marcus Moore Date: Wed, 29 Jan 2025 16:27:18 -0800 Subject: [PATCH 10/15] Reduce complexity --- app/Http/Controllers/ReportsController.php | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/app/Http/Controllers/ReportsController.php b/app/Http/Controllers/ReportsController.php index 5ce23138e2b1..fa437ed20ec3 100644 --- a/app/Http/Controllers/ReportsController.php +++ b/app/Http/Controllers/ReportsController.php @@ -1175,15 +1175,13 @@ public function sentAssetAcceptanceReminder(Request $request) : RedirectResponse } $email = $assetItem->assignedTo?->email; $locale = $assetItem->assignedTo?->locale; - // Only send notification if assigned - if ($email) { - Mail::to($email)->send((new CheckoutAssetMail($assetItem, $assetItem->assignedTo, $logItem->user, $acceptance, $logItem->note, firstTimeSending: false))->locale($locale)); - } - if ($email == ''){ + if (is_null($email) || $email === '') { return redirect()->route('reports/unaccepted_assets')->with('error', trans('general.no_email')); } + Mail::to($email)->send((new CheckoutAssetMail($assetItem, $assetItem->assignedTo, $logItem->user, $acceptance, $logItem->note, firstTimeSending: false))->locale($locale)); + return redirect()->route('reports/unaccepted_assets')->with('success', trans('admin/reports/general.reminder_sent')); } From 6a4a5d13806fead9cc5f19588dad4227956f2231 Mon Sep 17 00:00:00 2001 From: Marcus Moore Date: Thu, 30 Jan 2025 10:35:31 -0800 Subject: [PATCH 11/15] Add translation --- app/Mail/CheckoutAssetMail.php | 3 +-- resources/lang/en-US/mail.php | 1 + 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/app/Mail/CheckoutAssetMail.php b/app/Mail/CheckoutAssetMail.php index fbdaa4fcc0b4..d6ce123d4038 100644 --- a/app/Mail/CheckoutAssetMail.php +++ b/app/Mail/CheckoutAssetMail.php @@ -61,8 +61,7 @@ public function envelope(): Envelope $subject = trans('mail.Asset_Checkout_Notification'); if (!$this->firstTimeSending) { - // @todo: translate - $subject = 'Reminder: ' . $subject; + $subject = trans('mail.Asset_Checkout_Reminder_Notification'); } return new Envelope( diff --git a/resources/lang/en-US/mail.php b/resources/lang/en-US/mail.php index 7663a0167bb6..f7d3794dc35a 100644 --- a/resources/lang/en-US/mail.php +++ b/resources/lang/en-US/mail.php @@ -6,6 +6,7 @@ 'Accessory_Checkout_Notification' => 'Accessory checked out', 'Asset_Checkin_Notification' => 'Asset checked in', 'Asset_Checkout_Notification' => 'Asset checked out', + 'Asset_Checkout_Reminder_Notification' => 'Reminder: Asset checked out', 'Confirm_Accessory_Checkin' => 'Accessory checkin confirmation', 'Confirm_Asset_Checkin' => 'Asset checkin confirmation', 'Confirm_accessory_delivery' => 'Accessory delivery confirmation', From e94ee48f741846cd8ee4d51987fdb9848ac744f9 Mon Sep 17 00:00:00 2001 From: Marcus Moore Date: Thu, 30 Jan 2025 10:37:11 -0800 Subject: [PATCH 12/15] Extract helper --- app/Mail/CheckoutAssetMail.php | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/app/Mail/CheckoutAssetMail.php b/app/Mail/CheckoutAssetMail.php index d6ce123d4038..eb9619217fdf 100644 --- a/app/Mail/CheckoutAssetMail.php +++ b/app/Mail/CheckoutAssetMail.php @@ -58,15 +58,9 @@ public function envelope(): Envelope { $from = new Address(config('mail.from.address'), config('mail.from.name')); - $subject = trans('mail.Asset_Checkout_Notification'); - - if (!$this->firstTimeSending) { - $subject = trans('mail.Asset_Checkout_Reminder_Notification'); - } - return new Envelope( from: $from, - subject: $subject, + subject: $this->getSubject(), ); } @@ -117,4 +111,13 @@ public function attachments(): array { return []; } + + private function getSubject(): string + { + if ($this->firstTimeSending) { + return trans('mail.Asset_Checkout_Notification'); + } + + return trans('mail.Asset_Checkout_Reminder_Notification'); + } } From fc88b2487ff524d6515852b9fa8224263cdba411 Mon Sep 17 00:00:00 2001 From: Marcus Moore Date: Thu, 30 Jan 2025 11:44:37 -0800 Subject: [PATCH 13/15] Extract method --- .../factories/CheckoutAcceptanceFactory.php | 20 +++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/database/factories/CheckoutAcceptanceFactory.php b/database/factories/CheckoutAcceptanceFactory.php index 8dbb6712c6fb..a15e942a8473 100644 --- a/database/factories/CheckoutAcceptanceFactory.php +++ b/database/factories/CheckoutAcceptanceFactory.php @@ -27,15 +27,8 @@ public function definition() public function configure(): static { return $this->afterCreating(function (CheckoutAcceptance $acceptance) { - // @todo: add comment if ($acceptance->checkoutable instanceof Asset) { - $acceptance->checkoutable->assetlog()->create([ - 'action_type' => 'checkout', - 'target_id' => $acceptance->assigned_to_id, - 'target_type' => get_class($acceptance->assignedTo), - 'item_id' => $acceptance->checkoutable_id, - 'item_type' => $acceptance->checkoutable_type, - ]); + $this->createdAssociatedActionLogEntry($acceptance); } if ($acceptance->checkoutable instanceof Asset && $acceptance->assignedTo instanceof User) { @@ -70,4 +63,15 @@ public function accepted() 'declined_at' => null, ]); } + + private function createdAssociatedActionLogEntry(CheckoutAcceptance $acceptance): void + { + $acceptance->checkoutable->assetlog()->create([ + 'action_type' => 'checkout', + 'target_id' => $acceptance->assigned_to_id, + 'target_type' => get_class($acceptance->assignedTo), + 'item_id' => $acceptance->checkoutable_id, + 'item_type' => $acceptance->checkoutable_type, + ]); + } } From 7e9c564d0b1398eafaff1fedfc16773e11b5163d Mon Sep 17 00:00:00 2001 From: Marcus Moore Date: Thu, 30 Jan 2025 11:47:43 -0800 Subject: [PATCH 14/15] Simplify test --- .../Email/AssetAcceptanceReminderTest.php | 23 ++----------------- 1 file changed, 2 insertions(+), 21 deletions(-) diff --git a/tests/Feature/Notifications/Email/AssetAcceptanceReminderTest.php b/tests/Feature/Notifications/Email/AssetAcceptanceReminderTest.php index d7c89e041e2e..db3de3c54cf6 100644 --- a/tests/Feature/Notifications/Email/AssetAcceptanceReminderTest.php +++ b/tests/Feature/Notifications/Email/AssetAcceptanceReminderTest.php @@ -82,28 +82,9 @@ public function testUserWithoutEmailAddressHandledGracefully($callback) Mail::assertNotSent(CheckoutAssetMail::class); } - public static function acceptances() + public function testReminderIsSentToUser() { - yield 'User with locale set' => [ - function () { - return CheckoutAcceptance::factory()->pending()->create(); - } - ]; - - yield 'User without locale set' => [ - function () { - $checkoutAcceptance = CheckoutAcceptance::factory()->pending()->create(); - $checkoutAcceptance->assignedTo->update(['locale' => null]); - - return $checkoutAcceptance; - } - ]; - } - - #[DataProvider('acceptances')] - public function testReminderIsSentToUser($callback) - { - $checkoutAcceptance = $callback(); + $checkoutAcceptance = CheckoutAcceptance::factory()->pending()->create(); $this->actingAs(User::factory()->canViewReports()->create()) ->post($this->routeFor($checkoutAcceptance)) From 7cbb3f7e07f7820f665211e0e0e32a75644281fd Mon Sep 17 00:00:00 2001 From: Marcus Moore Date: Thu, 30 Jan 2025 11:48:55 -0800 Subject: [PATCH 15/15] Add assertion --- .../Feature/Notifications/Email/AssetAcceptanceReminderTest.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/Feature/Notifications/Email/AssetAcceptanceReminderTest.php b/tests/Feature/Notifications/Email/AssetAcceptanceReminderTest.php index db3de3c54cf6..85915352b78d 100644 --- a/tests/Feature/Notifications/Email/AssetAcceptanceReminderTest.php +++ b/tests/Feature/Notifications/Email/AssetAcceptanceReminderTest.php @@ -26,6 +26,8 @@ public function testMustHavePermissionToSendReminder() $this->actingAs($userWithoutPermission) ->post($this->routeFor($checkoutAcceptance)) ->assertForbidden(); + + Mail::assertNotSent(CheckoutAssetMail::class); } public function testReminderNotSentIfAcceptanceDoesNotExist()