diff --git a/src/jobs/scheduled/Cleaner.php b/src/jobs/scheduled/Cleaner.php index 5f7c8e5b..09bfbc02 100644 --- a/src/jobs/scheduled/Cleaner.php +++ b/src/jobs/scheduled/Cleaner.php @@ -4,7 +4,6 @@ use App\models; use App\services; -use App\utils; /** * Job to clean the system. @@ -45,7 +44,10 @@ public function perform(): void models\FetchLog::deleteOlderThan(\Minz\Time::ago(3, 'days')); models\Token::deleteExpired(); models\Session::deleteExpired(); - models\User::deleteNotValidatedOlderThan(\Minz\Time::ago(6, 'months')); + models\User::deleteInactiveAndNotified( + inactive_since: \Minz\Time::ago(6, 'months'), + notified_since: \Minz\Time::ago(1, 'month'), + ); models\Collection::deleteUnfollowedOlderThan($support_user->id, \Minz\Time::ago(7, 'days')); models\Link::deleteNotStoredOlderThan($support_user->id, \Minz\Time::ago(7, 'days')); /** @var int */ diff --git a/src/models/dao/User.php b/src/models/dao/User.php index 54db366e..fc9f4037 100644 --- a/src/models/dao/User.php +++ b/src/models/dao/User.php @@ -124,20 +124,28 @@ public static function countActivePerMonth(int $year): array } /** - * Delete not validated users older than the given date. + * Delete the inactive users that have been notified about it. */ - public static function deleteNotValidatedOlderThan(\DateTimeImmutable $date): bool - { + public static function deleteInactiveAndNotified( + \DateTimeImmutable $inactive_since, + \DateTimeImmutable $notified_since + ): bool { $sql = <<prepare($sql); return $statement->execute([ - $date->format(Database\Column::DATETIME_FORMAT), + ':inactive_since' => $inactive_since->format(Database\Column::DATETIME_FORMAT), + ':notified_since' => $notified_since->format(Database\Column::DATETIME_FORMAT), + ':support_email' => \Minz\Email::sanitize($support_email), ]); } diff --git a/tests/jobs/scheduled/CleanerTest.php b/tests/jobs/scheduled/CleanerTest.php index a80709e9..7c678694 100644 --- a/tests/jobs/scheduled/CleanerTest.php +++ b/tests/jobs/scheduled/CleanerTest.php @@ -137,18 +137,15 @@ public function testPerformKeepsCurrentSession(): void $this->assertTrue(models\Token::exists($token->token)); } - public function testPerformDeletesOldInvalidatedUsers(): void + public function testPerformDeletesInactiveAndNotifiedUsers(): void { - /** @var \DateTimeImmutable */ - $now = $this->fake('dateTime'); - $this->freeze($now); + $this->freeze(); $cleaner_job = new Cleaner(); - /** @var int */ - $months = $this->fake('numberBetween', 7, 24); - $created_at = \Minz\Time::ago($months, 'months'); + $inactivity_months = 6; + $notified_months = 1; $user = UserFactory::create([ - 'created_at' => $created_at, - 'validated_at' => null, + 'last_activity_at' => \Minz\Time::ago($inactivity_months, 'months'), + 'deletion_notified_at' => \Minz\Time::ago($notified_months, 'months'), ]); $cleaner_job->perform(); @@ -156,18 +153,14 @@ public function testPerformDeletesOldInvalidatedUsers(): void $this->assertFalse(models\User::exists($user->id)); } - public function testPerformKeepsOldValidatedUsers(): void + public function testPerformKeepsInactiveButNotNotifiedUsers(): void { - /** @var \DateTimeImmutable */ - $now = $this->fake('dateTime'); - $this->freeze($now); + $this->freeze(); $cleaner_job = new Cleaner(); - /** @var int */ - $months = $this->fake('numberBetween', 7, 24); - $created_at = \Minz\Time::ago($months, 'months'); + $inactivity_months = 6; $user = UserFactory::create([ - 'created_at' => $created_at, - 'validated_at' => \Minz\Time::now(), + 'last_activity_at' => \Minz\Time::ago($inactivity_months, 'months'), + 'deletion_notified_at' => null, ]); $cleaner_job->perform(); @@ -175,18 +168,65 @@ public function testPerformKeepsOldValidatedUsers(): void $this->assertTrue(models\User::exists($user->id)); } - public function testPerformKeepsRecentInvalidatedUsers(): void + public function testPerformKeepsRecentNotifiedUser(): void { - /** @var \DateTimeImmutable */ - $now = $this->fake('dateTime'); - $this->freeze($now); + $this->freeze(); $cleaner_job = new Cleaner(); - /** @var int */ - $months = $this->fake('numberBetween', 0, 6); - $created_at = \Minz\Time::ago($months, 'months'); + $inactivity_months = 6; + $notified_months = 0; $user = UserFactory::create([ - 'created_at' => $created_at, - 'validated_at' => null, + 'last_activity_at' => \Minz\Time::ago($inactivity_months, 'months'), + 'deletion_notified_at' => \Minz\Time::ago($notified_months, 'months'), + ]); + + $cleaner_job->perform(); + + $this->assertTrue(models\User::exists($user->id)); + } + + public function testPerformKeepsRecentInactiveButNotifiedUsers(): void + { + $this->freeze(); + $cleaner_job = new Cleaner(); + $inactivity_months = 5; + $notified_months = 1; + $user = UserFactory::create([ + 'last_activity_at' => \Minz\Time::ago($inactivity_months, 'months'), + 'deletion_notified_at' => \Minz\Time::ago($notified_months, 'months'), + ]); + + $cleaner_job->perform(); + + $this->assertTrue(models\User::exists($user->id)); + } + + public function testPerformKeepsActiveUsers(): void + { + $this->freeze(); + $cleaner_job = new Cleaner(); + $inactivity_months = 0; + $user = UserFactory::create([ + 'last_activity_at' => \Minz\Time::ago($inactivity_months, 'months'), + 'deletion_notified_at' => null, + ]); + + $cleaner_job->perform(); + + $this->assertTrue(models\User::exists($user->id)); + } + + public function testPerformKeepsSupportUser(): void + { + $this->freeze(); + $cleaner_job = new Cleaner(); + /** @var string */ + $support_email = \Minz\Configuration::$application['support_email']; + $inactivity_months = 6; + $notified_months = 1; + $user = UserFactory::create([ + 'last_activity_at' => \Minz\Time::ago($inactivity_months, 'months'), + 'deletion_notified_at' => \Minz\Time::ago($notified_months, 'months'), + 'email' => $support_email, ]); $cleaner_job->perform();