MDL-62035 core_comment: Update to deletion methods.
[moodle.git] / comment / tests / privacy_test.php
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  * Privacy tests for core_comment.
18  *
19  * @package    core_comment
20  * @category   test
21  * @copyright  2018 Adrian Greeve <adrian@moodle.com>
22  * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
23  */
25 defined('MOODLE_INTERNAL') || die();
26 global $CFG;
28 require_once($CFG->dirroot . '/comment/locallib.php');
29 require_once($CFG->dirroot . '/comment/lib.php');
31 use \core_privacy\tests\provider_testcase;
33 /**
34  * Unit tests for comment/classes/privacy/policy
35  *
36  * @copyright  2018 Adrian Greeve <adrian@moodle.com>
37  * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
38  */
39 class core_comment_privacy_testcase extends provider_testcase {
41     protected function setUp() {
42         $this->resetAfterTest();
43     }
45     /**
46      * Check the exporting of comments for a user id in a context.
47      */
48     public function test_export_comments() {
49         $course = $this->getDataGenerator()->create_course();
50         $context = context_course::instance($course->id);
52         $comment = $this->get_comment_object($context, $course);
54         $user1 = $this->getDataGenerator()->create_user();
55         $user2 = $this->getDataGenerator()->create_user();
57         // Add comments.
58         $comments = [];
59         $firstcomment = 'This is the first comment';
60         $this->setUser($user1);
61         $comment->add($firstcomment);
62         $comments[$user1->id] = $firstcomment;
64         $secondcomment = 'From the second user';
65         $this->setUser($user2);
66         $comment->add($secondcomment);
67         $comments[$user2->id] = $secondcomment;
69         // Retrieve comments only for user1.
70         $this->setUser($user1);
71         $writer = \core_privacy\local\request\writer::with_context($context);
72         \core_comment\privacy\provider::export_comments($context, 'block_comments', 'page_comments', 0, []);
74         $data = $writer->get_data([get_string('commentsubcontext', 'core_comment')]);
75         $exportedcomments = $data->comments;
77         // There is only one comment made by this user.
78         $this->assertCount(1, $exportedcomments);
79         $comment = reset($exportedcomments);
80         $this->assertEquals($comments[$user1->id], format_string($comment->content, FORMAT_PLAIN));
82         // Retrieve comments from any user.
83         \core_comment\privacy\provider::export_comments($context, 'block_comments', 'page_comments', 0, [], false);
85         $data = $writer->get_data([get_string('commentsubcontext', 'core_comment')]);
86         $exportedcomments = $data->comments;
88         // The whole conversation is two comments.
89         $this->assertCount(2, $exportedcomments);
90         foreach ($exportedcomments as $comment) {
91             $this->assertEquals($comments[$comment->userid], format_string($comment->content, FORMAT_PLAIN));
92         }
93     }
95     /**
96      * Tests the deletion of all comments in a context.
97      */
98     public function test_delete_comments_for_all_users() {
99         global $DB;
101         $course1 = $this->getDataGenerator()->create_course();
102         $course2 = $this->getDataGenerator()->create_course();
104         $coursecontext1 = context_course::instance($course1->id);
105         $coursecontext2 = context_course::instance($course2->id);
107         $user1 = $this->getDataGenerator()->create_user();
108         $user2 = $this->getDataGenerator()->create_user();
110         $comment1 = $this->get_comment_object($coursecontext1, $course1);
111         $comment2 = $this->get_comment_object($coursecontext2, $course2);
113         $this->setUser($user1);
114         $comment1->add('First comment for user 1 on comment 1');
115         $comment2->add('First comment for user 1 on comment 2');
116         $this->setUser($user2);
117         $comment1->add('First comment for user 2 on comment 1');
118         $comment2->add('First comment for user 2 on comment 2');
120         // Because of the way things are set up with validation, creating an entry with the same context in a different component
121         // or comment area is a huge pain. We're just going to jam entries into the table instead.
122         $record = (object) [
123             'contextid' => $coursecontext1->id,
124             'component' => 'block_comments',
125             'commentarea' => 'other_comments',
126             'itemid' => 2,
127             'content' => 'Comment user 1 different comment area',
128             'format' => 0,
129             'userid' => $user1->id,
130             'timecreated' => time()
131         ];
132         $DB->insert_record('comments', $record);
133         $record = (object) [
134             'contextid' => $coursecontext1->id,
135             'component' => 'tool_dataprivacy',
136             'commentarea' => 'page_comments',
137             'itemid' => 2,
138             'content' => 'Comment user 1 different component',
139             'format' => 0,
140             'userid' => $user1->id,
141             'timecreated' => time()
142         ];
143         $DB->insert_record('comments', $record);
145         // Delete only for the first context. All records in the comments table for this context should be removed.
146         \core_comment\privacy\provider::delete_comments_for_all_users($coursecontext1, 'block_comments', 'page_comments', 0);
147         // No records left here.
148         $this->assertCount(0, $comment1->get_comments());
149         // All of the records are left intact here.
150         $this->assertCount(2, $comment2->get_comments());
151         // Check the other comment area.
152         $result = $DB->get_records('comments', ['commentarea' => 'other_comments']);
153         $this->assertCount(1, $result);
154         $data = array_shift($result);
155         $this->assertEquals('other_comments', $data->commentarea);
156         // Check the different component, same commentarea.
157         $result = $DB->get_records('comments', ['component' => 'tool_dataprivacy']);
158         $this->assertCount(1, $result);
159         $data = array_shift($result);
160         $this->assertEquals('tool_dataprivacy', $data->component);
161     }
163     /**
164      * Tests deletion of comments for a specified user and contexts.
165      */
166     public function test_delete_comments_for_user() {
167         global $DB;
169         $course1 = $this->getDataGenerator()->create_course();
170         $course2 = $this->getDataGenerator()->create_course();
171         $course3 = $this->getDataGenerator()->create_course();
173         $coursecontext1 = context_course::instance($course1->id);
174         $coursecontext2 = context_course::instance($course2->id);
175         $coursecontext3 = context_course::instance($course3->id);
177         $user1 = $this->getDataGenerator()->create_user();
178         $user2 = $this->getDataGenerator()->create_user();
180         $comment1 = $this->get_comment_object($coursecontext1, $course1);
181         $comment2 = $this->get_comment_object($coursecontext2, $course2);
182         $comment3 = $this->get_comment_object($coursecontext3, $course3);
184         $this->setUser($user1);
185         $comment1->add('First comment for user 1');
186         $comment2->add('User 1 comment in second comment');
188         $this->setUser($user2);
189         $comment2->add('User two replied in comment two');
190         $comment3->add('Comment three for user 2.');
192         // Because of the way things are set up with validation, creating an entry with the same context in a different component
193         // or comment area is a huge pain. We're just going to jam entries into the table instead.
194         $record = (object) [
195             'contextid' => $coursecontext1->id,
196             'component' => 'block_comments',
197             'commentarea' => 'other_comments',
198             'itemid' => 2,
199             'content' => 'Comment user 1 different comment area',
200             'format' => 0,
201             'userid' => $user1->id,
202             'timecreated' => time()
203         ];
204         $DB->insert_record('comments', $record);
205         $record = (object) [
206             'contextid' => $coursecontext1->id,
207             'component' => 'tool_dataprivacy',
208             'commentarea' => 'page_comments',
209             'itemid' => 2,
210             'content' => 'Comment user 1 different component',
211             'format' => 0,
212             'userid' => $user1->id,
213             'timecreated' => time()
214         ];
215         $DB->insert_record('comments', $record);
217         // Delete the comments for user 1.
218         $approvedcontextlist = new core_privacy\tests\request\approved_contextlist($user1, 'block_comments',
219                 [$coursecontext1->id, $coursecontext2->id]);
220         \core_comment\privacy\provider::delete_comments_for_user($approvedcontextlist, 'block_comments', 'page_comments', 0);
222         // No comments left in comments 1 as only user 1 commented there.
223         $this->assertCount(0, $comment1->get_comments());
224         // Only user 2 comments left in comments 2.
225         $comment2comments = $comment2->get_comments();
226         $this->assertCount(1, $comment2comments);
227         $data = array_shift($comment2comments);
228         $this->assertEquals($user2->id, $data->userid);
229         // Nothing changed here as user 1 did not leave a comment.
230         $comment3comments = $comment3->get_comments();
231         $this->assertCount(1, $comment3comments);
232         $data = array_shift(($comment3comments));
233         $this->assertEquals($user2->id, $data->userid);
234         // Check the other comment area.
235         $result = $DB->get_records('comments', ['commentarea' => 'other_comments']);
236         $this->assertCount(1, $result);
237         $data = array_shift($result);
238         $this->assertEquals('other_comments', $data->commentarea);
239         // Check the different component, same commentarea.
240         $result = $DB->get_records('comments', ['component' => 'tool_dataprivacy']);
241         $this->assertCount(1, $result);
242         $data = array_shift($result);
243         $this->assertEquals('tool_dataprivacy', $data->component);
244     }
246     /**
247      * Creates a comment object
248      *
249      * @param  context $context A context object.
250      * @param  stdClass $course A course object.
251      * @return comment The comment object.
252      */
253     protected function get_comment_object($context, $course) {
254         // Comment on course page.
255         $args = new stdClass;
256         $args->context = $context;
257         $args->course = $course;
258         $args->area = 'page_comments';
259         $args->itemid = 0;
260         $args->component = 'block_comments';
261         $comment = new comment($args);
262         $comment->set_post_permission(true);
263         return $comment;
264     }