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\message\inbound;
18
 
19
use advanced_testcase;
20
use core\context\module;
21
use core\message\inbound\{manager, processing_failed_exception};
22
use mod_forum_generator;
23
use stdClass;
24
use Throwable;
25
 
26
/**
27
 * Unit tests for the reply handler
28
 *
29
 * @package     mod_forum
30
 * @covers      \mod_forum\message\inbound\reply_handler
31
 * @copyright   2024 Paul Holden <paulh@moodle.com>
32
 * @license     http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
33
 */
34
final class reply_handler_test extends advanced_testcase {
35
 
36
    /**
37
     * Test attachment processing
38
     */
39
    public function test_process_message_attachments(): void {
40
        global $DB;
41
 
42
        $this->resetAfterTest();
43
 
44
        $course = $this->getDataGenerator()->create_course(['maxbytes' => 1024]);
45
        $forum = $this->getDataGenerator()->create_module('forum', ['course' => $course->id, 'maxbytes' => 0]);
46
 
47
        $user = $this->getDataGenerator()->create_and_enrol($course);
48
        $this->setUser($user);
49
 
50
        [$discussion, $post] = $this->create_discussion_with_post($forum, $user);
51
 
52
        $output = $this->reply_handler_process_message($post, 'My reply', 'Hello', (object) [
53
            'filename' => 'Foo.txt',
54
            'content' => 'Foo',
55
            'filesize' => 3,
56
        ]);
57
 
58
        $this->assertMatchesRegularExpression('/Processing Foo.txt as an attachment./', $output);
59
        $this->assertMatchesRegularExpression('/Attaching Foo.txt to/', $output);
60
        $this->assertMatchesRegularExpression('/Created a post \d+ in \d+./', $output);
61
 
62
        // Assert our reply was added with attachment.
63
        $newpost = $DB->get_record('forum_posts', [
64
            'discussion' => $discussion->id,
65
            'subject' => 'My reply',
66
            'attachment' => 1,
67
        ], '*', MUST_EXIST);
68
 
69
        $attachments = get_file_storage()->get_area_files(
70
            module::instance($forum->cmid)->id,
71
            'mod_forum',
72
            'attachment',
73
            $newpost->id,
74
            'id',
75
            false,
76
        );
77
        $this->assertCount(1, $attachments);
78
        $this->assertEquals('Foo.txt', reset($attachments)->get_filename());
79
    }
80
 
81
    /**
82
     * Test attachment processing where maxbytes is exceeded
83
     */
84
    public function test_process_message_attachments_over_maxbytes(): void {
85
        $this->resetAfterTest();
86
 
87
        $course = $this->getDataGenerator()->create_course();
88
        $forum = $this->getDataGenerator()->create_module('forum', ['course' => $course->id, 'maxbytes' => 2]);
89
 
90
        $user = $this->getDataGenerator()->create_and_enrol($course);
91
        $this->setUser($user);
92
 
93
        [$discussion, $post] = $this->create_discussion_with_post($forum, $user);
94
 
95
        $this->expectException(processing_failed_exception::class);
96
        $this->expectExceptionMessage('Unable to post your reply, since the total attachment size (3 bytes) is greater than ' .
97
            'the maximum size allowed for the forum (2 bytes)');
98
        $this->reply_handler_process_message($post, 'My reply', 'Hello', (object) [
99
            'filename' => 'Foo.txt',
100
            'content' => 'Foo',
101
            'filesize' => 3,
102
        ]);
103
    }
104
 
105
    /**
106
     * Helper to generate discussion/post data
107
     *
108
     * @param stdClass $forum
109
     * @param stdClass $user
110
     * @return stdClass[]
111
     */
112
    private function create_discussion_with_post(stdClass $forum, stdClass $user): array {
113
        /** @var mod_forum_generator $generator */
114
        $generator = $this->getDataGenerator()->get_plugin_generator('mod_forum');
115
 
116
        $discussion = $generator->create_discussion(['course' => $forum->course, 'forum' => $forum->id, 'userid' => $user->id]);
117
        $post = $generator->create_post(['discussion' => $discussion->id, 'userid' => $user->id]);
118
 
119
        return [$discussion, $post];
120
    }
121
 
122
    /**
123
     * Helper to process message details using the reply handler
124
     *
125
     * @param stdClass $post
126
     * @param string $subject
127
     * @param string $message
128
     * @param stdClass $attachment
129
     * @return string Output buffer from the handler
130
     */
131
    private function reply_handler_process_message(
132
        stdClass $post,
133
        string $subject,
134
        string $message,
135
        stdClass $attachment,
136
    ): string {
137
 
138
        // Start capturing output.
139
        ob_start();
140
 
141
        /** @var reply_handler $handler */
142
        $handler = manager::get_handler(reply_handler::class);
143
 
144
        try {
145
            $handler->process_message(
146
                (object) [
147
                    'datavalue' => $post->id,
148
                ],
149
                (object) [
150
                    'envelope' => (object) [
151
                        'subject' => $subject,
152
                    ],
153
                    'plain' => $message,
154
                    'attachments' => [
155
                        'attachment' => [
156
                            $attachment,
157
                        ],
158
                    ],
159
                    'timestamp' => time(),
160
                ],
161
            );
162
        } catch (Throwable $ex) {
163
            ob_end_clean();
164
            throw $ex;
165
        }
166
 
167
        // Return captured output buffer.
168
        return (string) ob_get_clean();
169
    }
170
}