MDL-62035 core_comment: Update to deletion methods.
[moodle.git] / comment / tests / privacy_test.php
CommitLineData
5be028ab
AG
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 */
24
25defined('MOODLE_INTERNAL') || die();
26global $CFG;
27
28require_once($CFG->dirroot . '/comment/locallib.php');
29require_once($CFG->dirroot . '/comment/lib.php');
30
31use \core_privacy\tests\provider_testcase;
32
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 */
39class core_comment_privacy_testcase extends provider_testcase {
40
1b33e410
AG
41 protected function setUp() {
42 $this->resetAfterTest();
43 }
44
5be028ab
AG
45 /**
46 * Check the exporting of comments for a user id in a context.
47 */
48 public function test_export_comments() {
5be028ab
AG
49 $course = $this->getDataGenerator()->create_course();
50 $context = context_course::instance($course->id);
51
52 $comment = $this->get_comment_object($context, $course);
53
54 $user1 = $this->getDataGenerator()->create_user();
55 $user2 = $this->getDataGenerator()->create_user();
56
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;
63
64 $secondcomment = 'From the second user';
65 $this->setUser($user2);
66 $comment->add($secondcomment);
67 $comments[$user2->id] = $secondcomment;
68
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, []);
73
74 $data = $writer->get_data([get_string('commentsubcontext', 'core_comment')]);
75 $exportedcomments = $data->comments;
76
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));
81
82 // Retrieve comments from any user.
83 \core_comment\privacy\provider::export_comments($context, 'block_comments', 'page_comments', 0, [], false);
84
85 $data = $writer->get_data([get_string('commentsubcontext', 'core_comment')]);
86 $exportedcomments = $data->comments;
87
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 }
94
95 /**
96 * Tests the deletion of all comments in a context.
97 */
1b33e410
AG
98 public function test_delete_comments_for_all_users() {
99 global $DB;
5be028ab
AG
100
101 $course1 = $this->getDataGenerator()->create_course();
102 $course2 = $this->getDataGenerator()->create_course();
103
104 $coursecontext1 = context_course::instance($course1->id);
105 $coursecontext2 = context_course::instance($course2->id);
106
107 $user1 = $this->getDataGenerator()->create_user();
108 $user2 = $this->getDataGenerator()->create_user();
109
110 $comment1 = $this->get_comment_object($coursecontext1, $course1);
111 $comment2 = $this->get_comment_object($coursecontext2, $course2);
112
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');
119
1b33e410
AG
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);
144
5be028ab 145 // Delete only for the first context. All records in the comments table for this context should be removed.
1b33e410 146 \core_comment\privacy\provider::delete_comments_for_all_users($coursecontext1, 'block_comments', 'page_comments', 0);
5be028ab
AG
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());
1b33e410
AG
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);
5be028ab
AG
161 }
162
163 /**
164 * Tests deletion of comments for a specified user and contexts.
165 */
e98f0cf7 166 public function test_delete_comments_for_user() {
1b33e410 167 global $DB;
5be028ab
AG
168
169 $course1 = $this->getDataGenerator()->create_course();
170 $course2 = $this->getDataGenerator()->create_course();
171 $course3 = $this->getDataGenerator()->create_course();
172
173 $coursecontext1 = context_course::instance($course1->id);
174 $coursecontext2 = context_course::instance($course2->id);
175 $coursecontext3 = context_course::instance($course3->id);
176
177 $user1 = $this->getDataGenerator()->create_user();
178 $user2 = $this->getDataGenerator()->create_user();
179
180 $comment1 = $this->get_comment_object($coursecontext1, $course1);
181 $comment2 = $this->get_comment_object($coursecontext2, $course2);
182 $comment3 = $this->get_comment_object($coursecontext3, $course3);
183
184 $this->setUser($user1);
185 $comment1->add('First comment for user 1');
186 $comment2->add('User 1 comment in second comment');
187
188 $this->setUser($user2);
189 $comment2->add('User two replied in comment two');
190 $comment3->add('Comment three for user 2.');
191
1b33e410
AG
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);
216
5be028ab
AG
217 // Delete the comments for user 1.
218 $approvedcontextlist = new core_privacy\tests\request\approved_contextlist($user1, 'block_comments',
219 [$coursecontext1->id, $coursecontext2->id]);
1b33e410 220 \core_comment\privacy\provider::delete_comments_for_user($approvedcontextlist, 'block_comments', 'page_comments', 0);
5be028ab
AG
221
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);
1b33e410
AG
227 $data = array_shift($comment2comments);
228 $this->assertEquals($user2->id, $data->userid);
5be028ab
AG
229 // Nothing changed here as user 1 did not leave a comment.
230 $comment3comments = $comment3->get_comments();
231 $this->assertCount(1, $comment3comments);
1b33e410
AG
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);
5be028ab
AG
244 }
245
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 }
265}