Proyectos de Subversion Moodle

Rev

Rev 1 | | Comparar con el anterior | Ultima modificación | Ver Log |

Rev Autor Línea Nro. Línea
1 efrain 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
/**
18
 * The post exporter tests.
19
 *
20
 * @package    mod_forum
21
 * @copyright  2019 Ryan Wyllie <ryan@moodle.com>
22
 * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
23
 */
24
 
25
namespace mod_forum;
26
 
27
use mod_forum\local\entities\discussion as discussion_entity;
28
use mod_forum\local\entities\post as post_entity;
29
use mod_forum\local\exporters\post as post_exporter;
30
use mod_forum\local\managers\capability as capability_manager;
31
use mod_forum_tests_generator_trait;
32
 
33
defined('MOODLE_INTERNAL') || die();
34
 
35
global $CFG;
36
require_once(__DIR__ . '/generator_trait.php');
37
require_once($CFG->dirroot . '/rating/lib.php');
38
 
39
/**
40
 * The post exporter tests.
41
 *
42
 * @package    mod_forum
43
 * @copyright  2019 Ryan Wyllie <ryan@moodle.com>
44
 * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
45
 */
46
class exporters_post_test extends \advanced_testcase {
47
    // Make use of the test generator trait.
48
    use mod_forum_tests_generator_trait;
49
 
50
    /**
51
     * Test the export function returns expected values.
52
     *
53
     * @dataProvider export_post_provider
54
     * @param bool $istimed True if this is a timed post
55
     * @param int $addtime Seconds to be added to the current time
56
     */
11 efrain 57
    public function test_export_post($istimed = false, $addtime = 0): void {
1 efrain 58
        global $CFG, $PAGE;
59
        $this->resetAfterTest();
60
 
61
        $CFG->enableportfolios = true;
62
        $filestorage = get_file_storage();
63
        $renderer = $PAGE->get_renderer('core');
64
        $datagenerator = $this->getDataGenerator();
65
        $forumgenerator = $this->getDataGenerator()->get_plugin_generator('mod_forum');
66
        $user = $datagenerator->create_user();
67
        $course = $datagenerator->create_course();
68
        $forum = $datagenerator->create_module('forum', ['course' => $course->id]);
69
        $coursemodule = get_coursemodule_from_instance('forum', $forum->id);
70
        $context = \context_module::instance($coursemodule->id);
71
        $now = time();
72
 
73
        $forumgenparams = [
74
            'course' => $forum->course,
75
            'userid' => $user->id,
76
            'forum' => $forum->id,
77
        ];
78
        if ($istimed) {
79
            $forumgenparams['timestart'] = $now + $addtime;
80
        }
81
        $discussion = $forumgenerator->create_discussion((object) $forumgenparams);
82
 
83
        $post = $forumgenerator->create_post((object) [
84
            'discussion' => $discussion->id,
85
            'parent' => 0,
86
            'userid' => $user->id,
87
            'created' => $now,
88
            'modified' => $now,
89
            'subject' => 'This is the subject',
90
            'message' => 'This is the message',
91
            'messagetrust' => 1,
92
            'attachment' => 0,
93
            'totalscore' => 0,
94
            'mailnow' => 1,
95
            'deleted' => 0
96
        ]);
97
 
98
        \core_tag_tag::set_item_tags('mod_forum', 'forum_posts', $post->id, $context, ['foo', 'bar']);
99
        $tags = \core_tag_tag::get_item_tags('mod_forum', 'forum_posts', $post->id);
100
        $attachment = $filestorage->create_file_from_string(
101
            [
102
                'contextid' => $context->id,
103
                'component' => 'mod_forum',
104
                'filearea'  => 'attachment',
105
                'itemid'    => $post->id,
106
                'filepath'  => '/',
107
                'filename'  => 'example1.jpg',
108
            ],
109
            'image contents'
110
        );
111
 
112
        $canview = true;
113
        $canedit = true;
114
        $candelete = true;
115
        $cansplit = true;
116
        $canreply = true;
117
        $canexport = true;
118
        $cancontrolreadstatus = true;
119
        $canreplyprivately = true;
120
        $canenrol = true;
121
        $capabilitymanager = new test_capability_manager(
122
            $canview,
123
            $canedit,
124
            $candelete,
125
            $cansplit,
126
            $canreply,
127
            $canexport,
128
            $cancontrolreadstatus,
129
            $canreplyprivately,
130
            $canenrol
131
        );
132
        $managerfactory = \mod_forum\local\container::get_manager_factory();
133
        $entityfactory = \mod_forum\local\container::get_entity_factory();
134
        $forum = $entityfactory->get_forum_from_stdClass($forum, $context, $coursemodule, $course);
135
        $discussion = $entityfactory->get_discussion_from_stdClass($discussion);
136
        $post = $entityfactory->get_post_from_stdClass($post);
137
        $author = $entityfactory->get_author_from_stdClass($user);
138
        $authorcontext = \context_user::instance($author->get_id());
139
 
140
        $exporter = new post_exporter($post, [
141
            'legacydatamapperfactory' => \mod_forum\local\container::get_legacy_data_mapper_factory(),
142
            'capabilitymanager' => $capabilitymanager,
143
            'readreceiptcollection' => null,
144
            'urlfactory' => \mod_forum\local\container::get_url_factory(),
145
            'forum' => $forum,
146
            'discussion' => $discussion,
147
            'author' => $author,
148
            'authorcontextid' => $authorcontext->id,
149
            'user' => $user,
150
            'context' => $context,
151
            'authorgroups' => [],
152
            'attachments' => [$attachment],
153
            'tags' => $tags,
154
            'rating' => null,
155
            'includehtml' => true
156
        ]);
157
 
158
        $exportedpost = $exporter->export($renderer);
159
 
160
        $this->assertEquals('This is the subject', $exportedpost->subject);
161
        $this->assertEquals('This is the message', $exportedpost->message);
162
        $this->assertEquals($user->id, $exportedpost->author->id);
163
        $this->assertEquals($discussion->get_id(), $exportedpost->discussionid);
164
        $this->assertEquals(false, $exportedpost->hasparent);
165
        $this->assertEquals(null, $exportedpost->parentid);
166
        if ($istimed && ($addtime > 0)) {
167
            $this->assertEquals($now + $addtime, $exportedpost->timecreated);
168
        } else {
169
            $this->assertEquals($now, $exportedpost->timecreated);
170
        }
171
        $this->assertEquals(null, $exportedpost->unread);
172
        $this->assertEquals(false, $exportedpost->isdeleted);
173
        $this->assertEquals($canview, $exportedpost->capabilities['view']);
174
        $this->assertEquals($canedit, $exportedpost->capabilities['edit']);
175
        $this->assertEquals($candelete, $exportedpost->capabilities['delete']);
176
        $this->assertEquals($cansplit, $exportedpost->capabilities['split']);
177
        $this->assertEquals($canreply, $exportedpost->capabilities['reply']);
178
        $this->assertEquals($canexport, $exportedpost->capabilities['export']);
179
        $this->assertEquals($canenrol, $exportedpost->capabilities['selfenrol']);
180
        $this->assertEquals($cancontrolreadstatus, $exportedpost->capabilities['controlreadstatus']);
181
        $this->assertNotEmpty($exportedpost->urls['view']);
182
        $this->assertNotEmpty($exportedpost->urls['viewisolated']);
183
        $this->assertNotEmpty($exportedpost->urls['edit']);
184
        $this->assertNotEmpty($exportedpost->urls['delete']);
185
        $this->assertNotEmpty($exportedpost->urls['split']);
186
        $this->assertNotEmpty($exportedpost->urls['reply']);
187
        $this->assertNotEmpty($exportedpost->urls['markasread']);
188
        $this->assertNotEmpty($exportedpost->urls['markasunread']);
189
        $this->assertCount(1, $exportedpost->attachments);
190
        $this->assertEquals('example1.jpg', $exportedpost->attachments[0]->filename);
191
        $this->assertCount(2, $exportedpost->tags);
192
        $this->assertEquals('foo', $exportedpost->tags[0]['displayname']);
193
        $this->assertEquals('bar', $exportedpost->tags[1]['displayname']);
194
        $this->assertEquals(null, $exportedpost->html['rating']);
195
        $this->assertNotEquals(null, $exportedpost->html['taglist']);
196
        $this->assertNotEmpty($exportedpost->html['authorsubheading']);
197
    }
198
 
199
    /**
200
     * Data provider for test_export_post().
201
     *
202
     * @return array
203
     */
204
    public function export_post_provider(): array {
205
        return [
206
            'Simple export' => [
207
            ],
208
            'Test timed post future' => [
209
                true,
210
                1000
211
            ],
212
            'Test timed post past' => [
213
                true,
214
                -1000
215
            ],
216
        ];
217
    }
218
 
219
    /**
220
     * Test exporting of a deleted post.
221
     */
11 efrain 222
    public function test_export_deleted_post(): void {
1 efrain 223
        global $CFG, $PAGE;
224
        $this->resetAfterTest();
225
 
226
        $CFG->enableportfolios = true;
227
        $filestorage = get_file_storage();
228
        $renderer = $PAGE->get_renderer('core');
229
        $datagenerator = $this->getDataGenerator();
230
        $forumgenerator = $this->getDataGenerator()->get_plugin_generator('mod_forum');
231
        $user = $datagenerator->create_user();
232
        $course = $datagenerator->create_course();
233
        $forum = $datagenerator->create_module('forum', ['course' => $course->id]);
234
        $coursemodule = get_coursemodule_from_instance('forum', $forum->id);
235
        $context = \context_module::instance($coursemodule->id);
236
        $discussion = $forumgenerator->create_discussion((object) [
237
            'course' => $forum->course,
238
            'userid' => $user->id,
239
            'forum' => $forum->id
240
        ]);
241
        $now = time();
242
        $post = $forumgenerator->create_post((object) [
243
            'discussion' => $discussion->id,
244
            'parent' => 0,
245
            'userid' => $user->id,
246
            'created' => $now,
247
            'modified' => $now,
248
            'subject' => 'This is the subject',
249
            'message' => 'This is the message',
250
            'messagetrust' => 1,
251
            'attachment' => 0,
252
            'totalscore' => 0,
253
            'mailnow' => 1,
254
            'deleted' => 1
255
        ]);
256
 
257
        \core_tag_tag::set_item_tags('mod_forum', 'forum_posts', $post->id, $context, ['foo', 'bar']);
258
        $tags = \core_tag_tag::get_item_tags('mod_forum', 'forum_posts', $post->id);
259
        $attachment = $filestorage->create_file_from_string(
260
            [
261
                'contextid' => $context->id,
262
                'component' => 'mod_forum',
263
                'filearea'  => 'attachment',
264
                'itemid'    => $post->id,
265
                'filepath'  => '/',
266
                'filename'  => 'example1.jpg',
267
            ],
268
            'image contents'
269
        );
270
 
271
        $canview = true;
272
        $canedit = true;
273
        $candelete = true;
274
        $cansplit = true;
275
        $canreply = true;
276
        $canexport = true;
277
        $cancontrolreadstatus = true;
278
        $capabilitymanager = new test_capability_manager(
279
            $canview,
280
            $canedit,
281
            $candelete,
282
            $cansplit,
283
            $canreply,
284
            $canexport,
285
            $cancontrolreadstatus
286
        );
287
        $managerfactory = \mod_forum\local\container::get_manager_factory();
288
        $entityfactory = \mod_forum\local\container::get_entity_factory();
289
        $forum = $entityfactory->get_forum_from_stdClass($forum, $context, $coursemodule, $course);
290
        $discussion = $entityfactory->get_discussion_from_stdClass($discussion);
291
        $post = $entityfactory->get_post_from_stdClass($post);
292
        $author = $entityfactory->get_author_from_stdClass($user);
293
        $authorcontext = \context_user::instance($author->get_id());
294
 
295
        $exporter = new post_exporter($post, [
296
            'legacydatamapperfactory' => \mod_forum\local\container::get_legacy_data_mapper_factory(),
297
            'capabilitymanager' => $capabilitymanager,
298
            'readreceiptcollection' => null,
299
            'urlfactory' => \mod_forum\local\container::get_url_factory(),
300
            'forum' => $forum,
301
            'discussion' => $discussion,
302
            'author' => $author,
303
            'authorcontextid' => $authorcontext->id,
304
            'user' => $user,
305
            'context' => $context,
306
            'authorgroups' => [],
307
            'attachments' => [$attachment],
308
            'tags' => $tags,
309
            'rating' => null,
310
            'includehtml' => true
311
        ]);
312
 
313
        $exportedpost = $exporter->export($renderer);
314
 
315
        $this->assertNotEquals('This is the subject', $exportedpost->subject);
316
        $this->assertNotEquals('This is the message', $exportedpost->message);
317
        $this->assertEquals(null, $exportedpost->timecreated);
318
        $this->assertEquals(null, $exportedpost->unread);
319
        $this->assertEquals(true, $exportedpost->isdeleted);
320
        $this->assertEquals([], $exportedpost->attachments);
321
        $this->assertEquals([], $exportedpost->tags);
322
        $this->assertEquals(null, $exportedpost->html['rating']);
323
        $this->assertEquals(null, $exportedpost->html['taglist']);
324
        $this->assertEquals(null, $exportedpost->html['authorsubheading']);
325
    }
326
 
327
    /**
328
     * Test exporting of a post the user can't view.
329
     */
11 efrain 330
    public function test_export_post_no_view_capability(): void {
1 efrain 331
        global $CFG, $PAGE;
332
        $this->resetAfterTest();
333
 
334
        $CFG->enableportfolios = true;
335
        $filestorage = get_file_storage();
336
        $renderer = $PAGE->get_renderer('core');
337
        $datagenerator = $this->getDataGenerator();
338
        $forumgenerator = $this->getDataGenerator()->get_plugin_generator('mod_forum');
339
        $user = $datagenerator->create_user();
340
        $course = $datagenerator->create_course();
341
        $forum = $datagenerator->create_module('forum', ['course' => $course->id]);
342
        $coursemodule = get_coursemodule_from_instance('forum', $forum->id);
343
        $context = \context_module::instance($coursemodule->id);
344
        $discussion = $forumgenerator->create_discussion((object) [
345
            'course' => $forum->course,
346
            'userid' => $user->id,
347
            'forum' => $forum->id
348
        ]);
349
        $now = time();
350
        $post = $forumgenerator->create_post((object) [
351
            'discussion' => $discussion->id,
352
            'parent' => 0,
353
            'userid' => $user->id,
354
            'created' => $now,
355
            'modified' => $now,
356
            'subject' => 'This is the subject',
357
            'message' => 'This is the message',
358
            'messagetrust' => 1,
359
            'attachment' => 0,
360
            'totalscore' => 0,
361
            'mailnow' => 1,
362
            'deleted' => 0
363
        ]);
364
 
365
        \core_tag_tag::set_item_tags('mod_forum', 'forum_posts', $post->id, $context, ['foo', 'bar']);
366
        $tags = \core_tag_tag::get_item_tags('mod_forum', 'forum_posts', $post->id);
367
        $attachment = $filestorage->create_file_from_string(
368
            [
369
                'contextid' => $context->id,
370
                'component' => 'mod_forum',
371
                'filearea'  => 'attachment',
372
                'itemid'    => $post->id,
373
                'filepath'  => '/',
374
                'filename'  => 'example1.jpg',
375
            ],
376
            'image contents'
377
        );
378
 
379
        $canview = false;
380
        $canedit = true;
381
        $candelete = true;
382
        $cansplit = true;
383
        $canreply = true;
384
        $canexport = true;
385
        $cancontrolreadstatus = true;
386
        $capabilitymanager = new test_capability_manager(
387
            $canview,
388
            $canedit,
389
            $candelete,
390
            $cansplit,
391
            $canreply,
392
            $canexport,
393
            $cancontrolreadstatus
394
        );
395
        $managerfactory = \mod_forum\local\container::get_manager_factory();
396
        $entityfactory = \mod_forum\local\container::get_entity_factory();
397
        $forum = $entityfactory->get_forum_from_stdClass($forum, $context, $coursemodule, $course);
398
        $discussion = $entityfactory->get_discussion_from_stdClass($discussion);
399
        $post = $entityfactory->get_post_from_stdClass($post);
400
        $author = $entityfactory->get_author_from_stdClass($user);
401
        $authorcontext = \context_user::instance($author->get_id());
402
 
403
        $exporter = new post_exporter($post, [
404
            'legacydatamapperfactory' => \mod_forum\local\container::get_legacy_data_mapper_factory(),
405
            'capabilitymanager' => $capabilitymanager,
406
            'readreceiptcollection' => null,
407
            'urlfactory' => \mod_forum\local\container::get_url_factory(),
408
            'forum' => $forum,
409
            'discussion' => $discussion,
410
            'author' => $author,
411
            'authorcontextid' => $authorcontext->id,
412
            'user' => $user,
413
            'context' => $context,
414
            'authorgroups' => [],
415
            'attachments' => [$attachment],
416
            'tags' => $tags,
417
            'rating' => null,
418
            'includehtml' => true
419
        ]);
420
 
421
        $exportedpost = $exporter->export($renderer);
422
 
423
        $this->assertNotEquals('This is the subject', $exportedpost->subject);
424
        $this->assertNotEquals('This is the message', $exportedpost->message);
425
        $this->assertEquals(null, $exportedpost->timecreated);
426
        $this->assertEquals(null, $exportedpost->unread);
427
        $this->assertEquals(false, $exportedpost->isdeleted);
428
        $this->assertEquals([], $exportedpost->attachments);
429
        $this->assertEquals([], $exportedpost->tags);
430
        $this->assertEquals(null, $exportedpost->html['rating']);
431
        $this->assertEquals(null, $exportedpost->html['taglist']);
432
        $this->assertEquals(null, $exportedpost->html['authorsubheading']);
433
    }
434
}
435
 
436
/**
437
 * Test implementation of the capability manager.
438
 *
439
 * @copyright  2019 Ryan Wyllie <ryan@moodle.com>
440
 * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
441
 */
442
class test_capability_manager extends capability_manager {
443
    /** @var bool $view Value for can_view_post */
444
    private $view;
445
    /** @var bool $edit Value for can_edit_post */
446
    private $edit;
447
    /** @var bool $delete Value for can_delete_post */
448
    private $delete;
449
    /** @var bool $split Value for can_split_post */
450
    private $split;
451
    /** @var bool $reply Value for can_reply_to_post */
452
    private $reply;
453
    /** @var bool $export Value for can_export_post */
454
    private $export;
455
    /** @var bool $controlreadstatus Value for can_manually_control_post_read_status */
456
    private $controlreadstatus;
457
    /** @var bool $controlreadstatus Value for can_reply_privately_to_post */
458
    private $canreplyprivatelytopost;
459
    /** @var bool $canenrol Value for can_self_enrol */
460
    private $canenrol;
461
 
462
    /**
463
     * Constructor.
464
     *
465
     * @param bool $view Value for can_view_post
466
     * @param bool $edit Value for can_edit_post
467
     * @param bool $delete Value for can_delete_post
468
     * @param bool $split Value for can_split_post
469
     * @param bool $reply Value for can_reply_to_post
470
     * @param bool $export Value for can_export_post
471
     * @param bool $controlreadstatus Value for can_manually_control_post_read_status
472
     */
473
    public function __construct(
474
        bool $view = true,
475
        bool $edit = true,
476
        bool $delete = true,
477
        bool $split = true,
478
        bool $reply = true,
479
        bool $export = true,
480
        bool $controlreadstatus = true,
481
        bool $canreplyprivatelytopost = true,
482
        bool $canenrol = true
483
    ) {
484
        $this->view = $view;
485
        $this->edit = $edit;
486
        $this->delete = $delete;
487
        $this->split = $split;
488
        $this->reply = $reply;
489
        $this->export = $export;
490
        $this->controlreadstatus = $controlreadstatus;
491
        $this->canreplyprivatelytopost = $canreplyprivatelytopost;
492
        $this->canenrol = $canenrol;
493
    }
494
 
495
    /**
496
     * Override can_view_post
497
     *
498
     * @param \stdClass $user The user
499
     * @param discussion_entity $discussion The discussion
500
     * @param post_entity $post The post
501
     * @return bool
502
     */
503
    public function can_view_post(\stdClass $user, discussion_entity $discussion, post_entity $post): bool {
504
        return $this->view;
505
    }
506
 
507
    /**
508
     * Override can_edit_post
509
     *
510
     * @param \stdClass $user The user
511
     * @param discussion_entity $discussion The discussion
512
     * @param post_entity $post The post
513
     * @return bool
514
     */
515
    public function can_edit_post(\stdClass $user, discussion_entity $discussion, post_entity $post): bool {
516
        return $this->edit;
517
    }
518
 
519
    /**
520
     * Override can_delete_post
521
     *
522
     * @param \stdClass $user The user
523
     * @param discussion_entity $discussion The discussion
524
     * @param post_entity $post The post
525
     * @param bool $hasreplies
526
     * @return bool
527
     */
528
    public function can_delete_post(\stdClass $user, discussion_entity $discussion, post_entity $post,
529
                                    bool $hasreplies = false): bool {
530
        return $this->delete;
531
    }
532
 
533
    /**
534
     * Override can_split_post
535
     *
536
     * @param \stdClass $user The user
537
     * @param discussion_entity $discussion The discussion
538
     * @param post_entity $post The post
539
     * @return bool
540
     */
541
    public function can_split_post(\stdClass $user, discussion_entity $discussion, post_entity $post): bool {
542
        return $this->split;
543
    }
544
 
545
    /**
546
     * Override can_reply_to_post
547
     *
548
     * @param \stdClass $user The user
549
     * @param discussion_entity $discussion The discussion
550
     * @param post_entity $post The post
551
     * @return bool
552
     */
553
    public function can_reply_to_post(\stdClass $user, discussion_entity $discussion, post_entity $post): bool {
554
        return $this->reply;
555
    }
556
 
557
    /**
558
     * Override can_export_post
559
     *
560
     * @param \stdClass $user The user
561
     * @param post_entity $post The post
562
     * @return bool
563
     */
564
    public function can_export_post(\stdClass $user, post_entity $post): bool {
565
        return $this->export;
566
    }
567
 
568
    /**
569
     * Override can_manually_control_post_read_status
570
     *
571
     * @param \stdClass $user The user
572
     * @return bool
573
     */
574
    public function can_manually_control_post_read_status(\stdClass $user): bool {
575
        return $this->controlreadstatus;
576
    }
577
 
578
    /**
579
     * Override can_reply_privately_to_post
580
     * @param \stdClass $user
581
     * @param post_entity $post
582
     * @return bool
583
     */
584
    public function can_reply_privately_to_post(\stdClass $user, post_entity $post): bool {
585
        return $this->canreplyprivatelytopost;
586
    }
587
 
588
    /**
589
     * Override can_self_enrol
590
     * @param \stdClass $user
591
     * @return bool
592
     */
593
    public function can_self_enrol(\stdClass $user): bool {
594
        return $this->canenrol;
595
    }
596
}