mirror of
https://github.com/moodle/moodle.git
synced 2025-04-21 16:32:18 +02:00
MDL-80484 mod_forum : Add a check for an empty email address
Added a check for empty email address so that if the adhoc task for sending email notifcation to users for forum update fails because of empty email address an exception is not thrown as the exception was causing the the task for user with empty email address to keep requeuing again and again after failing. Wrote two test cases for testing if the fix has now prevented the task for empty email address to be requeued after failing and to test that if its still requeuing for other cases when the adhoc task fails for some other reason in this cause we are testing for bounce threshold.
This commit is contained in:
parent
ec7711b9a6
commit
6ee711fb6c
@ -184,9 +184,15 @@ class send_user_notifications extends \core\task\adhoc_task {
|
||||
}
|
||||
}
|
||||
|
||||
if ($errorcount > 0 and $sentcount === 0) {
|
||||
if ($errorcount > 0 && $sentcount === 0) {
|
||||
// All messages errored. So fail.
|
||||
throw new \moodle_exception('Error sending posts.');
|
||||
// Checking if the task failed because of empty email address so that it doesn't get rescheduled.
|
||||
if (!empty($this->recipient->email)) {
|
||||
throw new \moodle_exception('Error sending posts.');
|
||||
} else {
|
||||
mtrace("Failed to send emails for the user with ID ".
|
||||
$this->recipient->id ." due to an empty email address. Skipping re-queuing of the task.");
|
||||
}
|
||||
} else if ($errorcount > 0) {
|
||||
// Requeue failed messages as a new task.
|
||||
$task = new send_user_notifications();
|
||||
|
176
mod/forum/tests/task/send_user_notifications_test.php
Normal file
176
mod/forum/tests/task/send_user_notifications_test.php
Normal file
@ -0,0 +1,176 @@
|
||||
<?php
|
||||
// This file is part of Moodle - http://moodle.org/
|
||||
//
|
||||
// Moodle is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// Moodle is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
namespace mod_forum\task;
|
||||
|
||||
use Exception;
|
||||
use InvalidArgumentException;
|
||||
use RuntimeException;
|
||||
|
||||
/**
|
||||
* Unit tests for the send_user_notifications task in the forum module.
|
||||
*
|
||||
* This class contains test cases to ensure that the forum module's
|
||||
* send_user_notifications task functions as expected, particularly
|
||||
* when handling email notifications to users after forum posts.
|
||||
*
|
||||
* It tests different scenarios related to user email configurations,
|
||||
* such as when a user has an empty email address, when a user has exceeded
|
||||
* the bounce threshold, and how the system behaves when posts are attempted
|
||||
* to be sent under these conditions.
|
||||
*
|
||||
* Each test verifies that the appropriate exceptions are thrown, that
|
||||
* messages are correctly sent (or skipped), and that the task requeues
|
||||
* appropriately based on the user's email settings and other related conditions.
|
||||
*
|
||||
* @package mod_forum
|
||||
* @copyright 2024 Waleed ul hassan <waleed.hassan@catalyst-eu.net>
|
||||
* @license https://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
final class send_user_notifications_test extends \advanced_testcase {
|
||||
/**
|
||||
* Testcase to check send notification for post via email
|
||||
*
|
||||
* @covers \mod_forum\task\send_user_notifications
|
||||
* @dataProvider send_user_notifications_cases
|
||||
* @param array $userdata Test user for the case.
|
||||
* @param string $expectedstring Expected string during the test case.
|
||||
* @param array $expecteddebuggingstrings Expected debugging strings array.
|
||||
* @param bool $expectedassertion Expected adhoc task to be re queued or not.
|
||||
* @param array $userpreferences (optional) User preferences for the test case.
|
||||
* @throws InvalidArgumentException If the user data is invalid.
|
||||
* @throws RuntimeException If the notification fails to send.
|
||||
* @throws Exception For any other general errors.
|
||||
*/
|
||||
public function test_send_user_notifications(
|
||||
array $userdata,
|
||||
string $expectedstring,
|
||||
array $expecteddebuggingstrings,
|
||||
bool $expectedassertion,
|
||||
array $userpreferences = [],
|
||||
): void {
|
||||
global $CFG;
|
||||
require_once($CFG->dirroot . '/mod/forum/lib.php');
|
||||
$CFG->handlebounces = true;
|
||||
$this->resetAfterTest(true);
|
||||
$this->preventResetByRollback();
|
||||
$this->redirectEmails();
|
||||
|
||||
// Creating a user.
|
||||
$user = $this->getDataGenerator()->create_user($userdata);
|
||||
// Set user preferences.
|
||||
foreach ($userpreferences as $name => $value) {
|
||||
set_user_preference($name, $value, $user);
|
||||
}
|
||||
|
||||
// Create a course and a forum.
|
||||
$course = $this->getDataGenerator()->create_course();
|
||||
$forum = $this->getDataGenerator()->create_module('forum', [
|
||||
'course' => $course->id,
|
||||
'forcesubscribe' => \FORUM_FORCESUBSCRIBE,
|
||||
]);
|
||||
|
||||
// Create a discussion in the forum.
|
||||
$discussion = $this->getDataGenerator()->get_plugin_generator('mod_forum')->create_discussion([
|
||||
'course' => $course->id,
|
||||
'forum' => $forum->id,
|
||||
'userid' => $user->id,
|
||||
'message' => 'Test discussion',
|
||||
]);
|
||||
// Create a post in the discussion.
|
||||
$post = $this->getDataGenerator()->get_plugin_generator('mod_forum')->create_post([
|
||||
'course' => $course->id,
|
||||
'discussion' => $discussion->id,
|
||||
'userid' => $user->id,
|
||||
'message' => 'Test post',
|
||||
]);
|
||||
|
||||
// Setting placeholders for user id and post id.
|
||||
$expectedstring = sprintf($expectedstring, $user->id, $post->id, $user->id);
|
||||
$expecteddebuggingstrings = array_map(function($expecteddebuggingstring) use ($user) {
|
||||
return sprintf($expecteddebuggingstring, $user->id, $user->firstname . " " . $user->lastname);
|
||||
}, $expecteddebuggingstrings);
|
||||
|
||||
// Enroll the user in the course.
|
||||
$this->getDataGenerator()->enrol_user($user->id, $course->id);
|
||||
|
||||
// Trigger the send_user_notifications task.
|
||||
$task = new send_user_notifications();
|
||||
$task->set_userid($user->id);
|
||||
$task->set_custom_data($post->id);
|
||||
$this->expectOutputString($expectedstring);
|
||||
|
||||
// Testing if an exception is thrown because the task is re queued if an exception is thrown in the adhoc task.
|
||||
$expectedexception = 'Error sending posts.';
|
||||
try {
|
||||
$task->execute();
|
||||
} catch (\Exception $ex) {
|
||||
$this->assertEquals($expectedexception, $ex->errorcode);
|
||||
}
|
||||
if (count($expecteddebuggingstrings)) {
|
||||
$this->assertdebuggingcalledcount(count($expecteddebuggingstrings), $expecteddebuggingstrings);
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Data provider for test cases related to sending user notifications.
|
||||
*
|
||||
* This data provider generates various test cases for the `test_send_user_notifications` function.
|
||||
* Each test case consists of a user configuration, expected output strings, debugging messages, and assertions.
|
||||
*
|
||||
* @return array[] Array of test cases.
|
||||
*/
|
||||
public static function send_user_notifications_cases(): array {
|
||||
|
||||
return [
|
||||
[
|
||||
// Create a user with an empty email address.
|
||||
[
|
||||
'email' => '',
|
||||
'username' => 'testuser',
|
||||
],
|
||||
"Sending messages to testuser (%d)\n" .
|
||||
" Failed to send post %d\n" .
|
||||
"Sent 0 messages with 1 failures\n" .
|
||||
"Failed to send emails for the user with ID %d" .
|
||||
" due to an empty email address. Skipping re-queuing of the task.\n",
|
||||
[
|
||||
"Can not send email to user without email: %d",
|
||||
"Error calling message processor email",
|
||||
],
|
||||
false,
|
||||
],
|
||||
[
|
||||
// Create a user with bounce threshold.
|
||||
[
|
||||
'email' => 'bounce@example.com',
|
||||
'username' => 'bounceuser',
|
||||
],
|
||||
"Sending messages to bounceuser (%d)\n" .
|
||||
" Failed to send post %d\n" .
|
||||
"Sent 0 messages with 1 failures\n",
|
||||
[
|
||||
"email_to_user: User %d (%s) is over bounce threshold! Not sending.",
|
||||
"Error calling message processor email",
|
||||
],
|
||||
true,
|
||||
[
|
||||
'email_bounce_count' => 20,
|
||||
'email_send_count' => 20,
|
||||
],
|
||||
],
|
||||
];
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user