weekly release 4.0dev
[moodle.git] / contentbank / tests / contenttype_test.php
CommitLineData
bd4e0a76
AA
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 * Test for content bank contenttype class.
19 *
20 * @package core_contentbank
21 * @category test
22 * @copyright 2020 Amaia Anabitarte <amaia@moodle.com>
23 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
24 */
25
26namespace core_contentbank;
27
bd4e0a76
AA
28use stdClass;
29use context_system;
30use contenttype_testable\contenttype as contenttype;
31/**
32 * Test for content bank contenttype class.
33 *
34 * @package core_contentbank
35 * @category test
36 * @copyright 2020 Amaia Anabitarte <amaia@moodle.com>
37 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
38 * @coversDefaultClass \core_contentbank\contenttype
39 *
40 */
41class core_contenttype_contenttype_testcase extends \advanced_testcase {
42
c0d615e8
SA
43 /** @var int Identifier for the manager role. */
44 protected $managerroleid;
45
46 /** @var stdClass Manager user. */
47 protected $manager1;
48
49 /** @var stdClass Manager user. */
50 protected $manager2;
51
52 /** @var stdClass User. */
53 protected $user;
54
55 /** @var array List of contents created (every user has a key with contents created by her). */
56 protected $contents = [];
57
58 /** @var contenttype The contenttype instance. */
59 protected $contenttype;
60
f3126f84
SA
61 /**
62 * Setup to ensure that fixtures are loaded.
63 */
64 public static function setupBeforeClass(): void {
65 global $CFG;
66
67 require_once($CFG->dirroot . '/contentbank/tests/fixtures/testable_contenttype.php');
68 require_once($CFG->dirroot . '/contentbank/tests/fixtures/testable_content.php');
69 }
70
bd4e0a76
AA
71 /**
72 * Tests get_contenttype_name result.
73 *
74 * @covers ::get_contenttype_name
75 */
76 public function test_get_contenttype_name() {
77 $this->resetAfterTest();
78
79 $systemcontext = \context_system::instance();
80 $testable = new contenttype($systemcontext);
81
82 $this->assertEquals('contenttype_testable', $testable->get_contenttype_name());
83 }
84
85 /**
86 * Tests get_plugin_name result.
87 *
88 * @covers ::get_plugin_name
89 */
90 public function test_get_plugin_name() {
91 $this->resetAfterTest();
92
93 $systemcontext = \context_system::instance();
94 $testable = new contenttype($systemcontext);
95
96 $this->assertEquals('testable', $testable->get_plugin_name());
97 }
98
99 /**
100 * Tests get_icon result.
101 *
102 * @covers ::get_icon
103 */
104 public function test_get_icon() {
105 $this->resetAfterTest();
106
107 $systemcontext = \context_system::instance();
108 $testable = new contenttype($systemcontext);
6fc3477c
AA
109 $record = new stdClass();
110 $record->name = 'New content';
111 $content = $testable->create_content($record);
112 $icon = $testable->get_icon($content);
bd4e0a76
AA
113 $this->assertContains('archive', $icon);
114 }
115
116 /**
117 * Tests is_feature_supported behavior .
118 *
119 * @covers ::is_feature_supported
120 */
121 public function test_is_feature_supported() {
122 $this->resetAfterTest();
123
124 $systemcontext = \context_system::instance();
125 $testable = new contenttype($systemcontext);
126
127 $this->assertTrue($testable->is_feature_supported(contenttype::CAN_TEST));
128 $this->assertFalse($testable->is_feature_supported(contenttype::CAN_UPLOAD));
129 }
130
131 /**
132 * Tests can_upload behavior with no implemented upload feature.
133 *
134 * @covers ::can_upload
135 */
136 public function test_no_upload_feature_supported() {
137 $this->resetAfterTest();
138
139 $systemcontext = \context_system::instance();
140 $testable = new contenttype($systemcontext);
141
142 $this->setAdminUser();
143 $this->assertFalse($testable->is_feature_supported(contenttype::CAN_UPLOAD));
144 $this->assertFalse($testable->can_upload());
145 }
146
147 /**
148 * Test create_content() with empty data.
149 *
150 * @covers ::create_content
151 */
152 public function test_create_empty_content() {
153 $this->resetAfterTest();
154
155 // Create empty content.
156 $record = new stdClass();
157
158 $contenttype = new contenttype(context_system::instance());
159 $content = $contenttype->create_content($record);
160
161 $this->assertEquals('contenttype_testable', $content->get_content_type());
162 $this->assertInstanceOf('\\contenttype_testable\\content', $content);
163 }
164
165 /**
166 * Tests for behaviour of create_content() with data.
167 *
168 * @covers ::create_content
169 */
170 public function test_create_content() {
171 $this->resetAfterTest();
172
173 // Create content.
174 $record = new stdClass();
175 $record->name = 'Test content';
176 $record->configdata = '';
177 $record->contenttype = '';
178
179 $contenttype = new contenttype(context_system::instance());
180 $content = $contenttype->create_content($record);
181
182 $this->assertEquals('contenttype_testable', $content->get_content_type());
183 $this->assertInstanceOf('\\contenttype_testable\\content', $content);
184 }
c0d615e8 185
c0d615e8
SA
186 /**
187 * Test the behaviour of can_delete().
188 */
189 public function test_can_delete() {
190 global $DB;
191
192 $this->resetAfterTest();
193 $this->contenttype_setup_scenario_data();
194
195 $managercontent = array_shift($this->contents[$this->manager1->id]);
196 $usercontent = array_shift($this->contents[$this->user->id]);
197
198 // Check the content has been created as expected.
199 $records = $DB->count_records('contentbank_content');
200 $this->assertEquals(4, $records);
201
202 // Check user can only delete records created by her.
203 $this->setUser($this->user);
204 $this->assertFalse($this->contenttype->can_delete($managercontent));
205 $this->assertTrue($this->contenttype->can_delete($usercontent));
206
207 // Check manager can delete records all the records created.
208 $this->setUser($this->manager1);
209 $this->assertTrue($this->contenttype->can_delete($managercontent));
210 $this->assertTrue($this->contenttype->can_delete($usercontent));
211
212 // Unassign capability to manager role and check not can only delete their own records.
213 unassign_capability('moodle/contentbank:deleteanycontent', $this->managerroleid);
214 $this->assertTrue($this->contenttype->can_delete($managercontent));
215 $this->assertFalse($this->contenttype->can_delete($usercontent));
216 $this->setUser($this->manager2);
217 $this->assertFalse($this->contenttype->can_delete($managercontent));
218 $this->assertFalse($this->contenttype->can_delete($usercontent));
219 }
220
221 /**
222 * Test the behaviour of delete_content().
223 */
224 public function test_delete_content() {
225 global $DB;
226
227 $this->resetAfterTest();
228 $this->contenttype_setup_scenario_data();
229
230 // Check the content has been created as expected.
231 $this->assertEquals(4, $DB->count_records('contentbank_content'));
232
233 // Check the content is deleted as expected.
234 $this->setUser($this->manager1);
235 $content = array_shift($this->contents[$this->manager1->id]);
236 $deleted = $this->contenttype->delete_content($content);
237 $this->assertTrue($deleted);
238 $this->assertEquals(3, $DB->count_records('contentbank_content'));
239 }
240
241 /**
242 * Helper function to setup 3 users (manager1, manager2 and user) and 4 contents (3 created by manager1 and 1 by user).
243 */
244 protected function contenttype_setup_scenario_data(): void {
245 global $DB;
246 $systemcontext = context_system::instance();
247
248 // Create users.
249 $this->manager1 = $this->getDataGenerator()->create_user();
250 $this->manager2 = $this->getDataGenerator()->create_user();
251 $this->managerroleid = $DB->get_field('role', 'id', array('shortname' => 'manager'));
252 $this->getDataGenerator()->role_assign($this->managerroleid, $this->manager1->id);
253 $this->getDataGenerator()->role_assign($this->managerroleid, $this->manager2->id);
254 $this->user = $this->getDataGenerator()->create_user();
255
256 // Add some content to the content bank.
257 $generator = $this->getDataGenerator()->get_plugin_generator('core_contentbank');
258 $this->contents[$this->manager1->id] = $generator->generate_contentbank_data(null, 3, $this->manager1->id);
259 $this->contents[$this->user->id] = $generator->generate_contentbank_data(null, 1, $this->user->id);
260
261 $this->contenttype = new \contenttype_testable\contenttype($systemcontext);
262 }
3a6ca392
AA
263
264 /**
265 * Data provider for test_rename_content.
266 *
267 * @return array
268 */
269 public function rename_content_provider() {
270 return [
271 'Standard name' => ['New name', 'New name'],
272 'Name with digits' => ['Today is 17/04/2017', 'Today is 17/04/2017'],
273 'Name with symbols' => ['Follow us: @moodle', 'Follow us: @moodle'],
274 'Name with tags' => ['This is <b>bold</b>', 'This is bold'],
275 'Long name' => [str_repeat('a', 100), str_repeat('a', 100)],
276 'Too long name' => [str_repeat('a', 300), str_repeat('a', 255)]
277 ];
278 }
279
280 /**
281 * Test the behaviour of rename_content().
282 *
283 * @dataProvider rename_content_provider
284 * @param string $newname The name to set
285 * @param string $expected The name result
286 *
287 * @covers ::rename_content
288 */
289 public function test_rename_content(string $newname, string $expected) {
290 global $DB;
291
292 $this->resetAfterTest();
293
294 // Create course and teacher user.
295 $course = $this->getDataGenerator()->create_course();
296 $teacher = $this->getDataGenerator()->create_and_enrol($course, 'editingteacher');
297 $coursecontext = \context_course::instance($course->id);
298 $contenttype = new contenttype($coursecontext);
299
300 // Add some content to the content bank as teacher.
301 $this->setUser($teacher);
302 $generator = $this->getDataGenerator()->get_plugin_generator('core_contentbank');
303 $contents = $generator->generate_contentbank_data('contenttype_testable', 1, $teacher->id);
304 $content = array_shift($contents);
305
306 $oldname = $content->get_name();
307
308 // Check the content is renamed as expected by a user with permission.
309 $renamed = $contenttype->rename_content($content, $newname);
310 $this->assertTrue($renamed);
311 $record = $DB->get_record('contentbank_content', ['id' => $content->get_id()]);
312 $this->assertNotEquals($oldname, $record->name);
313 $this->assertEquals($expected, $record->name);
314 }
315
01003725
AA
316 /**
317 * Test the behaviour of move_content().
318 */
319 public function test_move_content() {
320 global $DB;
321
322 $this->resetAfterTest();
323 $systemcontext = context_system::instance();
324 $course = $this->getDataGenerator()->create_course();
325 $coursecontext = \context_course::instance($course->id);
326
327 // Add some content to the content bank.
328 $generator = $this->getDataGenerator()->get_plugin_generator('core_contentbank');
329 $systemcontents = $generator->generate_contentbank_data('contenttype_testable', 3, 0, $systemcontext);
330 $generator->generate_contentbank_data('contenttype_testable', 3, 0, $coursecontext);
331 $systemcontent = reset($systemcontents);
332
333 // Check the content has been created as expected.
334 $this->assertEquals(6, $DB->count_records('contentbank_content'));
335 $this->assertEquals(3, $DB->count_records('contentbank_content', ['contextid' => $systemcontext->id]));
336 $this->assertEquals(3, $DB->count_records('contentbank_content', ['contextid' => $coursecontext->id]));
337
338 // Check the content files has been created as expected.
339 $this->assertEquals(12, $DB->count_records('files', ['component' => 'contentbank']));
340 $this->assertEquals(6, $DB->count_records('files', ['component' => 'contentbank', 'contextid' => $systemcontext->id]));
341 $this->assertEquals(6, $DB->count_records('files', ['component' => 'contentbank', 'contextid' => $coursecontext->id]));
342
343 // Check the content is moved as expected.
344 $contenttype = new contenttype($systemcontext);
345 $this->assertTrue($contenttype->move_content($systemcontent, $coursecontext));
346 $this->assertEquals(6, $DB->count_records('contentbank_content'));
347 $this->assertEquals(2, $DB->count_records('contentbank_content', ['contextid' => $systemcontext->id]));
348 $this->assertEquals(4, $DB->count_records('contentbank_content', ['contextid' => $coursecontext->id]));
349
350 // Check the content files were moved as expected.
351 $this->assertEquals(12, $DB->count_records('files', ['component' => 'contentbank']));
352 $this->assertEquals(4, $DB->count_records('files', ['component' => 'contentbank', 'contextid' => $systemcontext->id]));
353 $this->assertEquals(8, $DB->count_records('files', ['component' => 'contentbank', 'contextid' => $coursecontext->id]));
354 }
355
3a6ca392
AA
356 /**
357 * Test the behaviour of can_manage().
358 *
359 * @covers ::can_manage
360 */
361 public function test_can_manage() {
362 global $DB, $USER;
363
364 $this->resetAfterTest();
365 $generator = $this->getDataGenerator()->get_plugin_generator('core_contentbank');
366
367 // Create course and teacher user.
368 $teacherroleid = $DB->get_field('role', 'id', ['shortname' => 'editingteacher']);
369 $course = $this->getDataGenerator()->create_course();
370 $teacher = $this->getDataGenerator()->create_and_enrol($course, 'editingteacher');
371 $manager = $this->getDataGenerator()->create_and_enrol($course, 'manager');
372 $coursecontext = \context_course::instance($course->id);
373
374 $contenttype = new contenttype($coursecontext);
375
376 // Add some content to the content bank as admin.
377 $this->setAdminUser();
378 $contentsbyadmin = $generator->generate_contentbank_data('contenttype_testable', 1, $USER->id, $coursecontext);
379 $contentbyadmin = array_shift($contentsbyadmin);
380
381 // Add some content to the content bank as teacher.
382 $contentsbyteacher = $generator->generate_contentbank_data('contenttype_testable', 1, $teacher->id, $coursecontext);
383 $contentbyteacher = array_shift($contentsbyteacher);
384
385 // Check the content has been created as expected.
386 $records = $DB->count_records('contentbank_content');
387 $this->assertEquals(2, $records);
388
389 // Check manager can manage by default all the contents created.
390 $this->setUser($manager);
391 $this->assertTrue($contenttype->can_manage($contentbyteacher));
392 $this->assertTrue($contenttype->can_manage($contentbyadmin));
393
394 // Check teacher can only edit their own content.
395 $this->setUser($teacher);
396 $this->assertTrue($contenttype->can_manage($contentbyteacher));
397 $this->assertFalse($contenttype->can_manage($contentbyadmin));
398
399 // Unassign capability to teacher role and check they not can not edit any content.
400 unassign_capability('moodle/contentbank:manageowncontent', $teacherroleid);
401 $this->assertFalse($contenttype->can_manage($contentbyteacher));
402 $this->assertFalse($contenttype->can_manage($contentbyadmin));
403 }
bd4e0a76 404}