feat(queue): Implement queueable email jobs with rate limiting
This commit is contained in:
parent
1e9566a289
commit
3d0d6c8bef
|
|
@ -4,16 +4,21 @@ namespace App\Mail\Drip;
|
|||
|
||||
use App\Models\User;
|
||||
use Illuminate\Bus\Queueable;
|
||||
use Illuminate\Contracts\Queue\ShouldQueue;
|
||||
use Illuminate\Mail\Mailable;
|
||||
use Illuminate\Mail\Mailables\Content;
|
||||
use Illuminate\Mail\Mailables\Envelope;
|
||||
use Illuminate\Queue\Middleware\RateLimited;
|
||||
use Illuminate\Queue\SerializesModels;
|
||||
|
||||
class FeedbackEmail extends Mailable
|
||||
class FeedbackEmail extends Mailable implements ShouldQueue
|
||||
{
|
||||
use Queueable, SerializesModels;
|
||||
|
||||
public function __construct(public User $user) {}
|
||||
public function __construct(public User $user)
|
||||
{
|
||||
$this->onQueue('emails');
|
||||
}
|
||||
|
||||
public function envelope(): Envelope
|
||||
{
|
||||
|
|
@ -31,4 +36,14 @@ class FeedbackEmail extends Mailable
|
|||
],
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the middleware the job should pass through.
|
||||
*
|
||||
* @return array<int, object>
|
||||
*/
|
||||
public function middleware(): array
|
||||
{
|
||||
return [new RateLimited('emails', releaseAfter: 1)];
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,16 +4,21 @@ namespace App\Mail\Drip;
|
|||
|
||||
use App\Models\User;
|
||||
use Illuminate\Bus\Queueable;
|
||||
use Illuminate\Contracts\Queue\ShouldQueue;
|
||||
use Illuminate\Mail\Mailable;
|
||||
use Illuminate\Mail\Mailables\Content;
|
||||
use Illuminate\Mail\Mailables\Envelope;
|
||||
use Illuminate\Queue\Middleware\RateLimited;
|
||||
use Illuminate\Queue\SerializesModels;
|
||||
|
||||
class ImportHelpEmail extends Mailable
|
||||
class ImportHelpEmail extends Mailable implements ShouldQueue
|
||||
{
|
||||
use Queueable, SerializesModels;
|
||||
|
||||
public function __construct(public User $user) {}
|
||||
public function __construct(public User $user)
|
||||
{
|
||||
$this->onQueue('emails');
|
||||
}
|
||||
|
||||
public function envelope(): Envelope
|
||||
{
|
||||
|
|
@ -31,4 +36,14 @@ class ImportHelpEmail extends Mailable
|
|||
],
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the middleware the job should pass through.
|
||||
*
|
||||
* @return array<int, object>
|
||||
*/
|
||||
public function middleware(): array
|
||||
{
|
||||
return [new RateLimited('emails', releaseAfter: 1)];
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,16 +4,21 @@ namespace App\Mail\Drip;
|
|||
|
||||
use App\Models\User;
|
||||
use Illuminate\Bus\Queueable;
|
||||
use Illuminate\Contracts\Queue\ShouldQueue;
|
||||
use Illuminate\Mail\Mailable;
|
||||
use Illuminate\Mail\Mailables\Content;
|
||||
use Illuminate\Mail\Mailables\Envelope;
|
||||
use Illuminate\Queue\Middleware\RateLimited;
|
||||
use Illuminate\Queue\SerializesModels;
|
||||
|
||||
class OnboardingReminderEmail extends Mailable
|
||||
class OnboardingReminderEmail extends Mailable implements ShouldQueue
|
||||
{
|
||||
use Queueable, SerializesModels;
|
||||
|
||||
public function __construct(public User $user) {}
|
||||
public function __construct(public User $user)
|
||||
{
|
||||
$this->onQueue('emails');
|
||||
}
|
||||
|
||||
public function envelope(): Envelope
|
||||
{
|
||||
|
|
@ -31,4 +36,14 @@ class OnboardingReminderEmail extends Mailable
|
|||
],
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the middleware the job should pass through.
|
||||
*
|
||||
* @return array<int, object>
|
||||
*/
|
||||
public function middleware(): array
|
||||
{
|
||||
return [new RateLimited('emails', releaseAfter: 1)];
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,16 +4,21 @@ namespace App\Mail\Drip;
|
|||
|
||||
use App\Models\User;
|
||||
use Illuminate\Bus\Queueable;
|
||||
use Illuminate\Contracts\Queue\ShouldQueue;
|
||||
use Illuminate\Mail\Mailable;
|
||||
use Illuminate\Mail\Mailables\Content;
|
||||
use Illuminate\Mail\Mailables\Envelope;
|
||||
use Illuminate\Queue\Middleware\RateLimited;
|
||||
use Illuminate\Queue\SerializesModels;
|
||||
|
||||
class PromoCodeEmail extends Mailable
|
||||
class PromoCodeEmail extends Mailable implements ShouldQueue
|
||||
{
|
||||
use Queueable, SerializesModels;
|
||||
|
||||
public function __construct(public User $user) {}
|
||||
public function __construct(public User $user)
|
||||
{
|
||||
$this->onQueue('emails');
|
||||
}
|
||||
|
||||
public function envelope(): Envelope
|
||||
{
|
||||
|
|
@ -32,4 +37,14 @@ class PromoCodeEmail extends Mailable
|
|||
],
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the middleware the job should pass through.
|
||||
*
|
||||
* @return array<int, object>
|
||||
*/
|
||||
public function middleware(): array
|
||||
{
|
||||
return [new RateLimited('emails', releaseAfter: 1)];
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,16 +4,21 @@ namespace App\Mail\Drip;
|
|||
|
||||
use App\Models\User;
|
||||
use Illuminate\Bus\Queueable;
|
||||
use Illuminate\Contracts\Queue\ShouldQueue;
|
||||
use Illuminate\Mail\Mailable;
|
||||
use Illuminate\Mail\Mailables\Content;
|
||||
use Illuminate\Mail\Mailables\Envelope;
|
||||
use Illuminate\Queue\Middleware\RateLimited;
|
||||
use Illuminate\Queue\SerializesModels;
|
||||
|
||||
class WelcomeEmail extends Mailable
|
||||
class WelcomeEmail extends Mailable implements ShouldQueue
|
||||
{
|
||||
use Queueable, SerializesModels;
|
||||
|
||||
public function __construct(public User $user) {}
|
||||
public function __construct(public User $user)
|
||||
{
|
||||
$this->onQueue('emails');
|
||||
}
|
||||
|
||||
public function envelope(): Envelope
|
||||
{
|
||||
|
|
@ -31,4 +36,14 @@ class WelcomeEmail extends Mailable
|
|||
],
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the middleware the job should pass through.
|
||||
*
|
||||
* @return array<int, object>
|
||||
*/
|
||||
public function middleware(): array
|
||||
{
|
||||
return [new RateLimited('emails', releaseAfter: 1)];
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@ use Illuminate\Contracts\Queue\ShouldQueue;
|
|||
use Illuminate\Mail\Mailable;
|
||||
use Illuminate\Mail\Mailables\Content;
|
||||
use Illuminate\Mail\Mailables\Envelope;
|
||||
use Illuminate\Queue\Middleware\RateLimited;
|
||||
use Illuminate\Queue\SerializesModels;
|
||||
|
||||
class UserLeadInvitation extends Mailable implements ShouldQueue
|
||||
|
|
@ -19,7 +20,7 @@ class UserLeadInvitation extends Mailable implements ShouldQueue
|
|||
*/
|
||||
public function __construct(public UserLead $lead)
|
||||
{
|
||||
//
|
||||
$this->onQueue('emails');
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -51,4 +52,14 @@ class UserLeadInvitation extends Mailable implements ShouldQueue
|
|||
{
|
||||
return [];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the middleware the job should pass through.
|
||||
*
|
||||
* @return array<int, object>
|
||||
*/
|
||||
public function middleware(): array
|
||||
{
|
||||
return [new RateLimited('emails', releaseAfter: 1)];
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,6 +3,8 @@
|
|||
namespace App\Providers;
|
||||
|
||||
use App\Http\Responses\RegisterResponse;
|
||||
use Illuminate\Cache\RateLimiting\Limit;
|
||||
use Illuminate\Support\Facades\RateLimiter;
|
||||
use Illuminate\Support\ServiceProvider;
|
||||
use Laravel\Fortify\Contracts\RegisterResponse as RegisterResponseContract;
|
||||
|
||||
|
|
@ -21,6 +23,8 @@ class AppServiceProvider extends ServiceProvider
|
|||
*/
|
||||
public function boot(): void
|
||||
{
|
||||
//
|
||||
RateLimiter::for('emails', function (object $job): Limit {
|
||||
return Limit::perSecond(1);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,7 @@
|
|||
<?php
|
||||
|
||||
use Illuminate\Support\Facades\Queue;
|
||||
|
||||
test('registration screen can be rendered', function () {
|
||||
$response = $this->get(route('register'));
|
||||
|
||||
|
|
@ -7,6 +9,8 @@ test('registration screen can be rendered', function () {
|
|||
});
|
||||
|
||||
test('new users can register', function () {
|
||||
Queue::fake();
|
||||
|
||||
$response = $this->post(route('register.store'), [
|
||||
'name' => 'Test User',
|
||||
'email' => 'test@example.com',
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@ test('feedback email is sent to non-subscribed users', function () {
|
|||
|
||||
SendFeedbackEmailJob::dispatchSync($user);
|
||||
|
||||
Mail::assertSent(FeedbackEmail::class, function ($mail) use ($user) {
|
||||
Mail::assertQueued(FeedbackEmail::class, function ($mail) use ($user) {
|
||||
return $mail->hasTo($user->email);
|
||||
});
|
||||
|
||||
|
|
@ -39,7 +39,7 @@ test('feedback email is not sent to subscribed users', function () {
|
|||
|
||||
SendFeedbackEmailJob::dispatchSync($user);
|
||||
|
||||
Mail::assertNotSent(FeedbackEmail::class);
|
||||
Mail::assertNotQueued(FeedbackEmail::class);
|
||||
});
|
||||
|
||||
test('feedback email is not sent if already received', function () {
|
||||
|
|
@ -49,5 +49,5 @@ test('feedback email is not sent if already received', function () {
|
|||
|
||||
SendFeedbackEmailJob::dispatchSync($user);
|
||||
|
||||
Mail::assertNotSent(FeedbackEmail::class);
|
||||
Mail::assertNotQueued(FeedbackEmail::class);
|
||||
});
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@ test('import help email is sent to onboarded users without transactions who are
|
|||
|
||||
SendImportHelpEmailJob::dispatchSync($user);
|
||||
|
||||
Mail::assertSent(ImportHelpEmail::class, function ($mail) use ($user) {
|
||||
Mail::assertQueued(ImportHelpEmail::class, function ($mail) use ($user) {
|
||||
return $mail->hasTo($user->email);
|
||||
});
|
||||
|
||||
|
|
@ -33,7 +33,7 @@ test('import help email is not sent to non-onboarded users', function () {
|
|||
|
||||
SendImportHelpEmailJob::dispatchSync($user);
|
||||
|
||||
Mail::assertNotSent(ImportHelpEmail::class);
|
||||
Mail::assertNotQueued(ImportHelpEmail::class);
|
||||
});
|
||||
|
||||
test('import help email is not sent to users with transactions', function () {
|
||||
|
|
@ -42,7 +42,7 @@ test('import help email is not sent to users with transactions', function () {
|
|||
|
||||
SendImportHelpEmailJob::dispatchSync($user);
|
||||
|
||||
Mail::assertNotSent(ImportHelpEmail::class);
|
||||
Mail::assertNotQueued(ImportHelpEmail::class);
|
||||
});
|
||||
|
||||
test('import help email is not sent to subscribed users', function () {
|
||||
|
|
@ -57,7 +57,7 @@ test('import help email is not sent to subscribed users', function () {
|
|||
|
||||
SendImportHelpEmailJob::dispatchSync($user);
|
||||
|
||||
Mail::assertNotSent(ImportHelpEmail::class);
|
||||
Mail::assertNotQueued(ImportHelpEmail::class);
|
||||
});
|
||||
|
||||
test('import help email is not sent if already received', function () {
|
||||
|
|
@ -67,5 +67,5 @@ test('import help email is not sent if already received', function () {
|
|||
|
||||
SendImportHelpEmailJob::dispatchSync($user);
|
||||
|
||||
Mail::assertNotSent(ImportHelpEmail::class);
|
||||
Mail::assertNotQueued(ImportHelpEmail::class);
|
||||
});
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@ test('onboarding reminder email is sent to non-onboarded users', function () {
|
|||
|
||||
SendOnboardingReminderEmailJob::dispatchSync($user);
|
||||
|
||||
Mail::assertSent(OnboardingReminderEmail::class, function ($mail) use ($user) {
|
||||
Mail::assertQueued(OnboardingReminderEmail::class, function ($mail) use ($user) {
|
||||
return $mail->hasTo($user->email);
|
||||
});
|
||||
|
||||
|
|
@ -31,7 +31,7 @@ test('onboarding reminder email is not sent to onboarded users', function () {
|
|||
|
||||
SendOnboardingReminderEmailJob::dispatchSync($user);
|
||||
|
||||
Mail::assertNotSent(OnboardingReminderEmail::class);
|
||||
Mail::assertNotQueued(OnboardingReminderEmail::class);
|
||||
|
||||
$this->assertDatabaseMissing('user_mail_logs', [
|
||||
'user_id' => $user->id,
|
||||
|
|
@ -46,5 +46,5 @@ test('onboarding reminder email is not sent if already received', function () {
|
|||
|
||||
SendOnboardingReminderEmailJob::dispatchSync($user);
|
||||
|
||||
Mail::assertNotSent(OnboardingReminderEmail::class);
|
||||
Mail::assertNotQueued(OnboardingReminderEmail::class);
|
||||
});
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@ test('promo code email is sent to onboarded users with transactions who are not
|
|||
|
||||
SendPromoCodeEmailJob::dispatchSync($user);
|
||||
|
||||
Mail::assertSent(PromoCodeEmail::class, function ($mail) use ($user) {
|
||||
Mail::assertQueued(PromoCodeEmail::class, function ($mail) use ($user) {
|
||||
return $mail->hasTo($user->email);
|
||||
});
|
||||
|
||||
|
|
@ -35,7 +35,7 @@ test('promo code email is not sent to non-onboarded users', function () {
|
|||
|
||||
SendPromoCodeEmailJob::dispatchSync($user);
|
||||
|
||||
Mail::assertNotSent(PromoCodeEmail::class);
|
||||
Mail::assertNotQueued(PromoCodeEmail::class);
|
||||
});
|
||||
|
||||
test('promo code email is not sent to users without transactions', function () {
|
||||
|
|
@ -43,7 +43,7 @@ test('promo code email is not sent to users without transactions', function () {
|
|||
|
||||
SendPromoCodeEmailJob::dispatchSync($user);
|
||||
|
||||
Mail::assertNotSent(PromoCodeEmail::class);
|
||||
Mail::assertNotQueued(PromoCodeEmail::class);
|
||||
});
|
||||
|
||||
test('promo code email is not sent to subscribed users', function () {
|
||||
|
|
@ -59,7 +59,7 @@ test('promo code email is not sent to subscribed users', function () {
|
|||
|
||||
SendPromoCodeEmailJob::dispatchSync($user);
|
||||
|
||||
Mail::assertNotSent(PromoCodeEmail::class);
|
||||
Mail::assertNotQueued(PromoCodeEmail::class);
|
||||
});
|
||||
|
||||
test('promo code email is not sent if already received', function () {
|
||||
|
|
@ -70,5 +70,5 @@ test('promo code email is not sent if already received', function () {
|
|||
|
||||
SendPromoCodeEmailJob::dispatchSync($user);
|
||||
|
||||
Mail::assertNotSent(PromoCodeEmail::class);
|
||||
Mail::assertNotQueued(PromoCodeEmail::class);
|
||||
});
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@ test('welcome email is sent and logged', function () {
|
|||
|
||||
SendWelcomeEmailJob::dispatchSync($user);
|
||||
|
||||
Mail::assertSent(WelcomeEmail::class, function ($mail) use ($user) {
|
||||
Mail::assertQueued(WelcomeEmail::class, function ($mail) use ($user) {
|
||||
return $mail->hasTo($user->email);
|
||||
});
|
||||
|
||||
|
|
@ -33,5 +33,5 @@ test('welcome email is not sent if already received', function () {
|
|||
|
||||
SendWelcomeEmailJob::dispatchSync($user);
|
||||
|
||||
Mail::assertNotSent(WelcomeEmail::class);
|
||||
Mail::assertNotQueued(WelcomeEmail::class);
|
||||
});
|
||||
|
|
|
|||
Loading…
Reference in New Issue