1
0
قرینه از https://github.com/matomo-org/matomo.git synced 2025-08-22 15:07:44 +00:00
Files
matomo/plugins/UsersManager/tests/Integration/InactiveUsersNotificationEmailTest.php
Michal Kleiner 7cc8a70b3d Add mechanism to send inactive users notification (#23425)
* Add new setting for enabling inactive user notifications (#23393)
* Migrate 'last seen' from options table to users table (#23388)
* Create scheduled task to send inactive users security notification (#23403)
* Simplify enrich user and remove surplus methods
* Create a language helper to run code using given user's preferred language
* Update UI test screenshots

---------

Co-authored-by: Nathan Gavin <nathangavin987@gmail.com>
2025-08-05 13:54:58 +12:00

191 خطوط
6.7 KiB
PHP

<?php
/**
* Matomo - free/libre analytics platform
*
* @link https://matomo.org
* @license https://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
*/
namespace Integration;
use PHPMailer\PHPMailer\PHPMailer;
use Piwik\Container\StaticContainer;
use Piwik\Date;
use Piwik\Plugins\UsersManager\Model as UsersManagerModel;
use Piwik\Plugins\UsersManager\SystemSettings;
use Piwik\Plugins\UsersManager\tests\Fixtures\Tokens as TokensFixture;
use Piwik\Plugins\UsersManager\UserNotifications\UserNotifierTask;
use Piwik\Tests\Framework\Fixture;
use Piwik\Tests\Framework\Mock\FakeAccess;
use Piwik\Tests\Framework\TestCase\IntegrationTestCase;
/**
* @group UsersManager
* @group InactiveUsersNotificationEmailTest
* @group UserNotifications
* @group Plugins
*/
class InactiveUsersNotificationEmailTest extends IntegrationTestCase
{
/**
* @var TokensFixture
*/
public static $fixture;
protected $capturedNotifications = [];
protected $task;
protected $systemSetting;
protected $userModel;
/**
* @throws \Exception
*/
public function setUp(): void
{
parent::setUp();
Fixture::createSuperUser();
Fixture::loadAllTranslations();
$this->task = new UserNotifierTask();
$this->userModel = new UsersManagerModel();
$settings = StaticContainer::get(SystemSettings::class);
$this->systemSetting = $settings->enableInactiveUsersNotifications;
$this->enableInactiveUsersNotifications();
}
public function tearDown(): void
{
$this->disableInactiveUsersNotifications();
}
private function enableInactiveUsersNotifications(): void
{
$this->systemSetting->setValue(true);
}
private function disableInactiveUsersNotifications(): void
{
$this->systemSetting->setValue(false);
}
/**
* @throws \Exception
*/
private function clearCaptureAndDispatch(bool $resetTsNotified = false): void
{
if ($resetTsNotified) {
self::$fixture->resetTsInactivityNotification();
}
$this->capturedNotifications = [];
$this->task->dispatchNotifications();
}
/**
* @throws \Exception
*/
public function testDispatchAuthTokenNotificationEmail()
{
Date::$now = Date::factory('2025-04-01')->getTimestamp();
// for standard 180 days, we have one notification for each of two superusers
$this->clearCaptureAndDispatch();
self::assertEquals(2, count($this->capturedNotifications));
// all notifications sent already, should be zero now
$this->clearCaptureAndDispatch();
self::assertEquals(0, count($this->capturedNotifications));
// after removing the notification timestamp, we should have two notifications again
$this->clearCaptureAndDispatch(true);
self::assertEquals(2, count($this->capturedNotifications));
self::assertEquals(['superUserLogin', 'user1'], array_keys($this->capturedNotifications));
// after removing super access from the second user, we should only get one notification
$this->userModel->setSuperUserAccess('user1', false);
$this->clearCaptureAndDispatch(true);
self::assertEquals(1, count($this->capturedNotifications));
self::assertEquals(['superUserLogin'], array_keys($this->capturedNotifications));
$notification = $this->capturedNotifications['superUserLogin'];
self::assertEquals(6, count($notification));
// if there's a token for a user, and it hasn't been used, and the user haven't logged in
// the token activity is the same as last seen for the user, which is both when they were created
self::assertEquals($notification[0]['last_token_activity'], $notification[0]['last_seen']);
// for user1, the fixture sets a custom last token activity
self::assertEquals('user1', $notification[1]['login']);
self::assertEquals('2025-02-01 00:00:00', $notification[1]['last_token_activity']);
// for user2, the fixture sets a custom last seen date, which is within 180 days from 'now'
self::assertEquals('user2', $notification[2]['login']);
self::assertEquals('2024-09-29 00:00:00', $notification[2]['last_seen']);
// for user4, the fixture does not create a token, so it was never used, and sets a custom last-seen date
self::assertEquals('user4', $notification[4]['login']);
self::assertEquals('2024-09-29 00:00:00', $notification[4]['last_seen']);
self::assertEquals('N/A', $notification[4]['last_token_activity']);
}
/**
* @throws \Exception
*/
public function testNoNotificationIsSentWhenTodayIsBeforeUsersCreated()
{
Date::$now = Date::factory('2023-12-01')->getTimestamp();
$this->clearCaptureAndDispatch(true);
self::assertEquals(0, count($this->capturedNotifications));
}
/**
* @throws \Exception
*/
public function testNoNotificationIsSentWhenFeatureDisabled()
{
$this->disableInactiveUsersNotifications();
$this->clearCaptureAndDispatch(true);
self::assertEquals(0, count($this->capturedNotifications));
}
public function provideContainerConfig(): array
{
return [
'Piwik\Access' => new FakeAccess(),
'observers.global' => \Piwik\DI::add([
['Test.Mail.send', \Piwik\DI::value(function (PHPMailer $mail) {
$body = $mail->createBody();
$body = preg_replace("/=[\r\n]+/", '', $body);
preg_match('|Hello, (.*?)!.*<tbody>(.*)</tbody>|isu', $body, $matches);
if (count($matches) === 3) {
$superuser = $matches[1];
preg_match_all('|<tr>(.*?)</tr>|isu', $matches[2], $tableRows);
if (count($tableRows) > 0) {
foreach ($tableRows[1] as $tableRow) {
preg_match_all('|<td.*?>(.*?)</td>|isu', $tableRow, $tableCells);
if (count($tableCells) === 2) {
$inactiveUserInfo = [
'login' => $tableCells[1][0],
'last_seen' => $tableCells[1][1],
'last_token_activity' => $tableCells[1][2],
];
$this->capturedNotifications[$superuser][] = $inactiveUserInfo;
}
}
}
}
})],
]),
];
}
}
InactiveUsersNotificationEmailTest::$fixture = new TokensFixture();