Proyectos de Subversion Moodle

Rev

| Ultima modificación | Ver Log |

Rev Autor Línea Nro. Línea
1441 ariadna 1
<?php
2
// This file is part of Moodle - http://moodle.org/
3
//
4
// Moodle is free software: you can redistribute it and/or modify
5
// it under the terms of the GNU General Public License as published by
6
// the Free Software Foundation, either version 3 of the License, or
7
// (at your option) any later version.
8
//
9
// Moodle is distributed in the hope that it will be useful,
10
// but WITHOUT ANY WARRANTY; without even the implied warranty of
11
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
// GNU General Public License for more details.
13
//
14
// You should have received a copy of the GNU General Public License
15
// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
16
 
17
namespace mod_forum\task;
18
 
19
use Exception;
20
use InvalidArgumentException;
21
use RuntimeException;
22
 
23
/**
24
 * Unit tests for the send_user_notifications task in the forum module.
25
 *
26
 * This class contains test cases to ensure that the forum module's
27
 * send_user_notifications task functions as expected, particularly
28
 * when handling email notifications to users after forum posts.
29
 *
30
 * It tests different scenarios related to user email configurations,
31
 * such as when a user has an empty email address, when a user has exceeded
32
 * the bounce threshold, and how the system behaves when posts are attempted
33
 * to be sent under these conditions.
34
 *
35
 * Each test verifies that the appropriate exceptions are thrown, that
36
 * messages are correctly sent (or skipped), and that the task requeues
37
 * appropriately based on the user's email settings and other related conditions.
38
 *
39
 * @package    mod_forum
40
 * @copyright   2024 Waleed ul hassan <waleed.hassan@catalyst-eu.net>
41
 * @license     https://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
42
 */
43
final class send_user_notifications_test extends \advanced_testcase {
44
    /**
45
     * Testcase to check send notification for post via email
46
     *
47
     * @covers \mod_forum\task\send_user_notifications
48
     * @dataProvider send_user_notifications_cases
49
     * @param array $userdata Test user for the case.
50
     * @param string $expectedstring Expected string during the test case.
51
     * @param array $expecteddebuggingstrings Expected debugging strings array.
52
     * @param bool $expectedassertion Expected adhoc task to be re queued or not.
53
     * @param array $userpreferences (optional) User preferences for the test case.
54
     * @throws InvalidArgumentException If the user data is invalid.
55
     * @throws RuntimeException If the notification fails to send.
56
     * @throws Exception For any other general errors.
57
     */
58
    public function test_send_user_notifications(
59
        array $userdata,
60
        string $expectedstring,
61
        array $expecteddebuggingstrings,
62
        bool $expectedassertion,
63
        array $userpreferences = [],
64
    ): void {
65
        global $CFG;
66
        require_once($CFG->dirroot . '/mod/forum/lib.php');
67
        $CFG->handlebounces = true;
68
        $this->resetAfterTest(true);
69
        $this->preventResetByRollback();
70
        $this->redirectEmails();
71
 
72
        // Creating a user.
73
        $user = $this->getDataGenerator()->create_user($userdata);
74
        // Set user preferences.
75
        foreach ($userpreferences as $name => $value) {
76
            set_user_preference($name, $value, $user);
77
        }
78
 
79
        // Create a course and a forum.
80
        $course = $this->getDataGenerator()->create_course();
81
        $forum = $this->getDataGenerator()->create_module('forum', [
82
            'course' => $course->id,
83
            'forcesubscribe' => \FORUM_FORCESUBSCRIBE,
84
        ]);
85
 
86
        // Create a discussion in the forum.
87
        $discussion = $this->getDataGenerator()->get_plugin_generator('mod_forum')->create_discussion([
88
            'course' => $course->id,
89
            'forum' => $forum->id,
90
            'userid' => $user->id,
91
            'message' => 'Test discussion',
92
        ]);
93
        // Create a post in the discussion.
94
        $post = $this->getDataGenerator()->get_plugin_generator('mod_forum')->create_post([
95
            'course' => $course->id,
96
            'discussion' => $discussion->id,
97
            'userid' => $user->id,
98
            'message' => 'Test post',
99
        ]);
100
 
101
        // Setting placeholders for user id and post id.
102
        $expectedstring = sprintf($expectedstring, $user->id, $post->id, $user->id);
103
        $expecteddebuggingstrings = array_map(function($expecteddebuggingstring) use ($user) {
104
            return sprintf($expecteddebuggingstring, $user->id, $user->firstname . " " . $user->lastname);
105
        }, $expecteddebuggingstrings);
106
 
107
        // Enroll the user in the course.
108
        $this->getDataGenerator()->enrol_user($user->id, $course->id);
109
 
110
        // Trigger the send_user_notifications task.
111
        $task = new send_user_notifications();
112
        $task->set_userid($user->id);
113
        $task->set_custom_data($post->id);
114
        $this->expectOutputString($expectedstring);
115
 
116
        // Testing if an exception is thrown because the task is re queued if an exception is thrown in the adhoc task.
117
        $expectedexception = 'Error sending posts.';
118
        try {
119
            $task->execute();
120
        } catch (\Exception $ex) {
121
            $this->assertEquals($expectedexception, $ex->errorcode);
122
        }
123
        if (count($expecteddebuggingstrings)) {
124
            $this->assertdebuggingcalledcount(count($expecteddebuggingstrings), $expecteddebuggingstrings);
125
        }
126
    }
127
    /**
128
     * Data provider for test cases related to sending user notifications.
129
     *
130
     * This data provider generates various test cases for the `test_send_user_notifications` function.
131
     * Each test case consists of a user configuration, expected output strings, debugging messages, and assertions.
132
     *
133
     * @return array[] Array of test cases.
134
     */
135
    public static function send_user_notifications_cases(): array {
136
 
137
        return [
138
            [
139
                // Create a user with an empty email address.
140
                [
141
                    'email' => '',
142
                    'username' => 'testuser',
143
                ],
144
                "Sending messages to testuser (%d)\n" .
145
                    "  Failed to send post %d\n" .
146
                    "Sent 0 messages with 1 failures\n" .
147
                    "Failed to send emails for the user with ID %d" .
148
                    " due to an empty email address. Skipping re-queuing of the task.\n",
149
                [
150
                    "Can not send email to user without email: %d",
151
                    "Error calling message processor email",
152
                ],
153
                false,
154
            ],
155
            [
156
                // Create a user with bounce threshold.
157
                [
158
                    'email' => 'bounce@example.com',
159
                    'username' => 'bounceuser',
160
                ],
161
                "Sending messages to bounceuser (%d)\n" .
162
                    "  Failed to send post %d\n" .
163
                    "Sent 0 messages with 1 failures\n",
164
                [
165
                    "email_to_user: User %d (%s) is over bounce threshold! Not sending.",
166
                    "Error calling message processor email",
167
                ],
168
                true,
169
                [
170
                    'email_bounce_count' => 20,
171
                    'email_send_count' => 20,
172
                ],
173
            ],
174
        ];
175
    }
176
}