The issue you're facing with the Mail::queued assertion not being reached could be due to a few reasons. Let's go through some potential solutions and debugging steps:
-
Ensure Queue is Set to Sync: Since you're using Redis in your non-test environment, make sure that your test environment is correctly set to use the
syncdriver. You've already setQUEUE_CONNECTION=syncin your.env.test, which is correct. Double-check that your test environment is loading this configuration. -
Check Job Dispatching: Ensure that the job
SendAdminNewUserRequestis being dispatched correctly. You can add addorLog::infostatement in thehandlemethod of the job to confirm it's being executed. -
Verify Mail Fake Setup: Ensure that
Mail::fake()is called before the action that triggers the mail. In your test, it seems to be set up correctly, but double-check the order of operations. -
Check for Transaction Issues: Since you're using database transactions, ensure that the transaction is committed before the job is dispatched. In your
AuthController, the transaction is committed after dispatching the job, which is correct. However, if there's any exception or issue before the commit, the job might not have the expected data. -
Debug the Test: Add a
ddorLog::infoin thehandlemethod of theSendAdminNewUserRequestjob to ensure it's being called and that theMail::to(...)->queue(...)line is executed. -
Test the Mail Directly: Instead of relying on the job, you can test the mail directly by calling the
handlemethod of the job in your test to see if the mail is queued as expected.
Here's a modified version of your test to help debug:
/** @test */
public function it_registers_users_and_emails_admins(): void
{
Queue::fake();
Queue::except([SendAdminNewUserRequest::class]);
Mail::fake();
$user = User::factory()->make();
$group = Group::factory()->create();
$groupadmin = User::factory()
->hasAttached($group)
->create([
'is_group_admin_of' => $group->getKey(),
]);
$response = $this->postJson(route('api.register'), [
'name' => $user->name,
'email' => $user->email,
'password' => self::SAFE_PASSWORD,
'password_confirmation' => self::SAFE_PASSWORD,
'terms_accepted' => true,
'group_id' => $group->getKey()
]);
$response->assertCreated();
// Directly call the job's handle method to test mail sending
$newUserRequest = NewUserRequest::where('user_id', $user->getKey())->first();
$job = new SendAdminNewUserRequest($newUserRequest->getKey());
$job->handle();
Mail::assertQueued(NewUserRequestAdminNotify::class, function (NewUserRequestAdminNotify $mail) use ($user, $groupadmin) {
$mail->assertSeeInHtml($user->email);
$mail->assertTo([$groupadmin->email]);
$this->assertTrue(str_contains($mail->subject, $user->email));
return true;
});
$this->assertDatabaseHas('new_user_requests', [
'user_id' => $user->getKey(),
'group_id' => 1,
'status' => 'pending'
]);
}
This approach directly tests the mail sending logic by calling the job's handle method, which can help isolate whether the issue is with the job dispatching or the mail queuing. Adjust the test as needed based on your application's specifics.