user_registration_reminder-1.x-dev/tests/src/Kernel/UserRegistrationReminderKernelTest.php
tests/src/Kernel/UserRegistrationReminderKernelTest.php
<?php
declare(strict_types=1);
namespace Drupal\Tests\user_registration_reminder\Kernel;
use Drupal\KernelTests\KernelTestBase;
use Drupal\Tests\user\Traits\UserCreationTrait;
use Drupal\user\UserInterface;
/**
* Kernel tests for user_registration_reminder.
*
* @group user_registration_reminder
*/
final class UserRegistrationReminderKernelTest extends KernelTestBase {
use UserCreationTrait;
/**
* {@inheritdoc}
*/
protected static $modules = [
'system',
'user',
'user_registration_reminder',
];
/**
* The user registration reminder service.
*
* @var \Drupal\user_registration_reminder\Manager
*/
protected $manager;
/**
* {@inheritdoc}
*/
protected function setUp(): void {
parent::setUp();
$this->installConfig(['system', 'user', 'user_registration_reminder']);
$this->installEntitySchema('user');
$this->installSchema('user', ['users_data']);
// Set required site configuration.
$this->config('system.site')
->set('mail', 'mailtest@example.com')
->set('name', 'Drupal')
->save();
$this->manager = \Drupal::service('user_registration_reminder.manager');
}
/**
* Creates an active user who never logged in before.
*/
protected function createNotLoggedInUser(?int $created = NULL): UserInterface {
$user = $this->createUser();
$user->activate();
if ($created !== NULL) {
$user->set('created', $created);
$user->set('changed', $created);
}
$user->save();
return $user;
}
/**
* Sets the reminder config to enabled.
*/
protected function reminderConfigSetEnabled($status = TRUE) {
$this->config('user_registration_reminder.settings')
->set('enabled', $status)
->save();
}
/**
* Sets all delay to 1 in reminders escalation steps.
*/
protected function reminderConfigSetMinimumDelay() {
// Set delay to 1 second, so the reminders will be triggered right away:
$this->config('user_registration_reminder.settings')
->set('reminder_escalations.0.delay', 1)
->set('reminder_escalations.1.delay', 1)
->set('reminder_escalations.2.delay', 1)
->set('final_action.delay', 1)
->save();
}
/**
* Tests runRegistrationReminder disabled with no results expected.
*/
public function testRunRegistrationReminderNoSendDisabled(): void {
// Reset the state variable that holds sent messages.
\Drupal::state()->set('system.test_mail_collector', []);
$this->reminderConfigSetEnabled(FALSE);
// Create a user that registered 30 days ago:
$this->createNotLoggedInUser(time() - 2592000);
$this->manager->runRegistrationReminder();
// Retrieve sent message.
$captured_emails = \Drupal::state()->get('system.test_mail_collector');
$sent_message = end($captured_emails);
// Assert that no message was sent.
$this->assertFalse($sent_message);
}
/**
* Tests runRegistrationReminder with no results expected.
*/
public function testRunRegistrationReminderNoSendBeforeDelay(): void {
$this->reminderConfigSetEnabled();
// Reset the state variable that holds sent messages.
\Drupal::state()->set('system.test_mail_collector', []);
// Create some fresh users:
$this->createNotLoggedInUser();
$this->manager->runRegistrationReminder();
// Retrieve sent message.
$captured_emails = \Drupal::state()->get('system.test_mail_collector');
$sent_message = end($captured_emails);
// Assert that no message was sent.
$this->assertFalse($sent_message);
}
/**
* Tests the runRegistrationReminder method with a mature user.
*/
public function testRunRegistrationReminderPreexistingUser(): void {
$this->reminderConfigSetEnabled();
$this->reminderConfigSetMinimumDelay();
// Reset the state variable that holds sent messages.
\Drupal::state()->set('system.test_mail_collector', []);
$siteName = \Drupal::config('system.site')->get('name');
// Create user 30 days ago:
$user30DaysAgo = $this->createNotLoggedInUser(time() - 2592000);
$this->manager->runRegistrationReminder();
// Retrieve sent message.
$captured_emails = \Drupal::state()->get('system.test_mail_collector');
$this->assertCount(1, $captured_emails);
$mail = $captured_emails[0];
$this->assertEquals('Reminder for your account ' . $user30DaysAgo->getAccountName() . ' at ' . $siteName, $mail['subject']);
$this->assertStringContainsString($user30DaysAgo->getAccountName() . ', thank you for registering at ' . $siteName . ' recently. You may now log in by clicking', str_replace("\n", ' ', $mail['body']));
// Wait for delay of 1s:
sleep(1);
$this->manager->runRegistrationReminder();
// Wait for the reminders to be triggered:
// Now the second reminder should be triggered:
// Retrieve sent message.
$captured_emails = \Drupal::state()->get('system.test_mail_collector');
$this->assertCount(2, $captured_emails);
$mail = $captured_emails[1];
$this->assertEquals('Second reminder for your account ' . $user30DaysAgo->getAccountName() . ' at ' . $siteName, $mail['subject']);
$this->assertStringContainsString($user30DaysAgo->getAccountName() . ', thank you for registering at ' . $siteName . ' some days ago.', str_replace("\n", ' ', $mail['body']));
// Wait for delay of 1s:
sleep(1);
$this->manager->runRegistrationReminder();
// Wait for the reminders to be triggered:
// Now the third reminder should be triggered:
// Retrieve sent message.
$captured_emails = \Drupal::state()->get('system.test_mail_collector');
$this->assertCount(3, $captured_emails);
$mail = $captured_emails[2];
$this->assertEquals('[IMPORTANT] Final reminder for your account ' . $user30DaysAgo->getAccountName() . ' at ' . $siteName, $mail['subject']);
$this->assertStringContainsString($user30DaysAgo->getAccountName() . ', this is the last reminder for your account "' . $user30DaysAgo->getAccountName() . '" at ' . $siteName, str_replace("\n", ' ', $mail['body']));
}
/**
* Tests reminder with multiple preexisting users.
*/
public function testRunRegistrationReminderMultiplePreexistingUsers(): void {
$this->reminderConfigSetEnabled();
$this->reminderConfigSetMinimumDelay();
// Reset the state variable that holds sent messages.
\Drupal::state()->set('system.test_mail_collector', []);
// Create 2 fresh users (Which are not expected to retrieve mails):
$this->createNotLoggedInUser();
$this->createNotLoggedInUser();
// And 4 old ones:
$this->createNotLoggedInUser(0);
$this->createNotLoggedInUser(0);
$this->createNotLoggedInUser(0);
$this->createNotLoggedInUser(0);
$this->manager->runRegistrationReminder();
$captured_emails = \Drupal::state()->get('system.test_mail_collector');
$this->assertCount(4, $captured_emails);
// Wait for delay of 1s:
sleep(1);
$this->manager->runRegistrationReminder();
$captured_emails = \Drupal::state()->get('system.test_mail_collector');
$this->assertCount(8, $captured_emails);
// Wait for delay of 1s:
sleep(1);
$this->manager->runRegistrationReminder();
$captured_emails = \Drupal::state()->get('system.test_mail_collector');
$this->assertCount(12, $captured_emails);
// No further mail should be sent:
// Wait for delay of 1s:
sleep(1);
$this->manager->runRegistrationReminder();
$captured_emails = \Drupal::state()->get('system.test_mail_collector');
$this->assertCount(12, $captured_emails);
}
/**
* Tests reminder with multiple preexisting users.
*/
public function testRunRegistrationReminderDisabledZeroDelayEscalation(): void {
$this->reminderConfigSetEnabled();
$this->config('user_registration_reminder.settings')
->set('reminder_escalations.0.delay', 1)
->set('reminder_escalations.1.delay', 1)
->set('reminder_escalations.2.delay', 0)
->set('final_action.delay', 1)
->save();
// Reset the state variable that holds sent messages.
\Drupal::state()->set('system.test_mail_collector', []);
// Create 2 fresh users (Which are not expected to retrieve mails):
$this->createNotLoggedInUser();
$this->createNotLoggedInUser();
// And 4 old ones:
$this->createNotLoggedInUser(0);
$this->createNotLoggedInUser(0);
$this->createNotLoggedInUser(0);
$this->createNotLoggedInUser(0);
$this->manager->runRegistrationReminder();
$captured_emails = \Drupal::state()->get('system.test_mail_collector');
$this->assertCount(4, $captured_emails);
// Wait for delay of 1s:
sleep(1);
$this->manager->runRegistrationReminder();
$captured_emails = \Drupal::state()->get('system.test_mail_collector');
$this->assertCount(8, $captured_emails);
// Wait for delay of 1s:
sleep(1);
$this->manager->runRegistrationReminder();
$captured_emails = \Drupal::state()->get('system.test_mail_collector');
$this->assertCount(8, $captured_emails);
// No further mail should be sent:
// Wait for delay of 1s:
sleep(1);
$this->manager->runRegistrationReminder();
$captured_emails = \Drupal::state()->get('system.test_mail_collector');
$this->assertCount(8, $captured_emails);
}
/**
* Tests the BCC mail functionality.
*/
public function testRunRegistrationReminderBcc(): void {
$this->reminderConfigSetEnabled();
$this->reminderConfigSetMinimumDelay();
$bcc = 'info@example.com';
// Send bcc:
$this->config('user_registration_reminder.settings')
->set('email_bcc', $bcc)
->save();
// Create 1 user.
$this->createNotLoggedInUser(0);
// Reset the state variable that holds sent messages.
\Drupal::state()->set('system.test_mail_collector', []);
$this->manager->runRegistrationReminder();
$captured_emails = \Drupal::state()->get('system.test_mail_collector');
$this->assertEquals($bcc, $captured_emails[0]['headers']['Bcc']);
$this->assertCount(1, $captured_emails);
}
/**
* Tests the final none action.
*/
public function testRunRegistrationReminderNoneAction(): void {
$this->reminderConfigSetEnabled();
$this->reminderConfigSetMinimumDelay();
$this->config('user_registration_reminder.settings')
->set('final_action.action', 'none')
->save();
$this->reminderConfigSetEnabled();
$this->reminderConfigSetMinimumDelay();
// Reset the state variable that holds sent messages.
\Drupal::state()->set('system.test_mail_collector', []);
// Create an old user.
$this->createNotLoggedInUser(0);
$this->manager->runRegistrationReminder();
$captured_emails = \Drupal::state()->get('system.test_mail_collector');
$this->assertCount(1, $captured_emails);
// Wait for delay of 1s:
sleep(1);
$this->manager->runRegistrationReminder();
$captured_emails = \Drupal::state()->get('system.test_mail_collector');
$this->assertCount(2, $captured_emails);
// Wait for delay of 1s:
sleep(1);
$this->manager->runRegistrationReminder();
$captured_emails = \Drupal::state()->get('system.test_mail_collector');
$this->assertCount(3, $captured_emails);
// Wait for delay of 1s:
sleep(1);
$this->manager->runRegistrationReminder();
$captured_emails = \Drupal::state()->get('system.test_mail_collector');
// No further mail should be sent:
$this->assertCount(3, $captured_emails);
// Reset the state variable that holds sent messages.
\Drupal::state()->set('system.test_mail_collector', []);
}
/**
* Tests the final block action.
*/
public function testRunRegistrationReminderBlockAction(): void {
$this->reminderConfigSetEnabled();
$this->reminderConfigSetMinimumDelay();
$this->config('user_registration_reminder.settings')
->set('final_action.action', 'block')
->save();
// Reset the state variable that holds sent messages.
\Drupal::state()->set('system.test_mail_collector', []);
$user = $this->createNotLoggedInUser(0);
$this->manager->runRegistrationReminder();
// Wait for delay of 1s:
sleep(1);
$this->manager->runRegistrationReminder();
// Wait for delay of 1s:
sleep(1);
$this->manager->runRegistrationReminder();
// Wait for delay of 1s:
sleep(1);
$this->manager->runRegistrationReminder();
$captured_emails = \Drupal::state()->get('system.test_mail_collector');
// No further mail should be sent:
$this->assertCount(3, $captured_emails);
$user_storage = $this->container->get('entity_type.manager')->getStorage('user');
$user_storage->resetCache([$user->id()]);
$user = $user_storage->load($user->id());
$this->assertFalse($user->isActive());
}
/**
* Tests the final cancel delete action.
*/
public function testRunRegistrationReminderCancelDeleteAction(): void {
$this->reminderConfigSetEnabled();
$this->reminderConfigSetMinimumDelay();
$this->config('user_registration_reminder.settings')
->set('final_action.action', 'delete')
->save();
// Reset the state variable that holds sent messages.
\Drupal::state()->set('system.test_mail_collector', []);
$user = $this->createNotLoggedInUser(0);
$this->manager->runRegistrationReminder();
// Wait for delay of 1s:
sleep(1);
$this->manager->runRegistrationReminder();
// Wait for delay of 1s:
sleep(1);
$this->manager->runRegistrationReminder();
// Wait for delay of 1s:
sleep(1);
$this->manager->runRegistrationReminder();
$captured_emails = \Drupal::state()->get('system.test_mail_collector');
// No further mail should be sent:
$this->assertCount(3, $captured_emails);
$user_storage = $this->container->get('entity_type.manager')->getStorage('user');
$user_storage->resetCache([$user->id()]);
$user = $user_storage->load($user->id());
// @todo Find out why the user still exists here!
// $this->assertEmpty($user);
}
/**
* Tests the final cancel delete action.
*/
public function testRunRegistrationReminderCancelBlockAction(): void {
$this->reminderConfigSetEnabled();
$this->reminderConfigSetMinimumDelay();
$this->config('user_registration_reminder.settings')
->set('final_action.action', 'block')
->save();
// Reset the state variable that holds sent messages.
\Drupal::state()->set('system.test_mail_collector', []);
$user = $this->createNotLoggedInUser(0);
$this->manager->runRegistrationReminder();
// Wait for delay of 1s:
sleep(1);
$this->manager->runRegistrationReminder();
// Wait for delay of 1s:
sleep(1);
$this->manager->runRegistrationReminder();
// Wait for delay of 1s:
sleep(1);
$this->manager->runRegistrationReminder();
$captured_emails = \Drupal::state()->get('system.test_mail_collector');
// No further mail should be sent:
$this->assertCount(3, $captured_emails);
$user_storage = $this->container->get('entity_type.manager')->getStorage('user');
$user_storage->resetCache([$user->id()]);
$user = $user_storage->load($user->id());
$this->assertFalse($user->isActive());
}
}
