2 // This file is part of Moodle - http://moodle.org/
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.
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.
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/>.
18 * Test for content bank contenttype class.
20 * @package core_contentbank
22 * @copyright 2020 Amaia Anabitarte <amaia@moodle.com>
23 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
26 namespace core_contentbank;
28 defined('MOODLE_INTERNAL') || die();
31 require_once($CFG->dirroot . '/contentbank/tests/fixtures/testable_contenttype.php');
32 require_once($CFG->dirroot . '/contentbank/tests/fixtures/testable_content.php');
36 use contenttype_testable\contenttype as contenttype;
38 * Test for content bank contenttype class.
40 * @package core_contentbank
42 * @copyright 2020 Amaia Anabitarte <amaia@moodle.com>
43 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
44 * @coversDefaultClass \core_contentbank\contenttype
47 class core_contenttype_contenttype_testcase extends \advanced_testcase {
49 /** @var int Identifier for the manager role. */
50 protected $managerroleid;
52 /** @var stdClass Manager user. */
55 /** @var stdClass Manager user. */
58 /** @var stdClass User. */
61 /** @var array List of contents created (every user has a key with contents created by her). */
62 protected $contents = [];
64 /** @var contenttype The contenttype instance. */
65 protected $contenttype;
68 * Tests get_contenttype_name result.
70 * @covers ::get_contenttype_name
72 public function test_get_contenttype_name() {
73 $this->resetAfterTest();
75 $systemcontext = \context_system::instance();
76 $testable = new contenttype($systemcontext);
78 $this->assertEquals('contenttype_testable', $testable->get_contenttype_name());
82 * Tests get_plugin_name result.
84 * @covers ::get_plugin_name
86 public function test_get_plugin_name() {
87 $this->resetAfterTest();
89 $systemcontext = \context_system::instance();
90 $testable = new contenttype($systemcontext);
92 $this->assertEquals('testable', $testable->get_plugin_name());
96 * Tests get_icon result.
100 public function test_get_icon() {
101 $this->resetAfterTest();
103 $systemcontext = \context_system::instance();
104 $testable = new contenttype($systemcontext);
105 $icon = $testable->get_icon('new content');
106 $this->assertContains('archive', $icon);
110 * Tests is_feature_supported behavior .
112 * @covers ::is_feature_supported
114 public function test_is_feature_supported() {
115 $this->resetAfterTest();
117 $systemcontext = \context_system::instance();
118 $testable = new contenttype($systemcontext);
120 $this->assertTrue($testable->is_feature_supported(contenttype::CAN_TEST));
121 $this->assertFalse($testable->is_feature_supported(contenttype::CAN_UPLOAD));
125 * Tests can_upload behavior with no implemented upload feature.
127 * @covers ::can_upload
129 public function test_no_upload_feature_supported() {
130 $this->resetAfterTest();
132 $systemcontext = \context_system::instance();
133 $testable = new contenttype($systemcontext);
135 $this->setAdminUser();
136 $this->assertFalse($testable->is_feature_supported(contenttype::CAN_UPLOAD));
137 $this->assertFalse($testable->can_upload());
141 * Test create_content() with empty data.
143 * @covers ::create_content
145 public function test_create_empty_content() {
146 $this->resetAfterTest();
148 // Create empty content.
149 $record = new stdClass();
151 $contenttype = new contenttype(context_system::instance());
152 $content = $contenttype->create_content($record);
154 $this->assertEquals('contenttype_testable', $content->get_content_type());
155 $this->assertInstanceOf('\\contenttype_testable\\content', $content);
159 * Tests for behaviour of create_content() with data.
161 * @covers ::create_content
163 public function test_create_content() {
164 $this->resetAfterTest();
167 $record = new stdClass();
168 $record->name = 'Test content';
169 $record->configdata = '';
170 $record->contenttype = '';
172 $contenttype = new contenttype(context_system::instance());
173 $content = $contenttype->create_content($record);
175 $this->assertEquals('contenttype_testable', $content->get_content_type());
176 $this->assertInstanceOf('\\contenttype_testable\\content', $content);
180 * Test the behaviour of can_delete().
182 public function test_can_delete() {
185 $this->resetAfterTest();
186 $this->contenttype_setup_scenario_data();
188 $managercontent = array_shift($this->contents[$this->manager1->id]);
189 $usercontent = array_shift($this->contents[$this->user->id]);
191 // Check the content has been created as expected.
192 $records = $DB->count_records('contentbank_content');
193 $this->assertEquals(4, $records);
195 // Check user can only delete records created by her.
196 $this->setUser($this->user);
197 $this->assertFalse($this->contenttype->can_delete($managercontent));
198 $this->assertTrue($this->contenttype->can_delete($usercontent));
200 // Check manager can delete records all the records created.
201 $this->setUser($this->manager1);
202 $this->assertTrue($this->contenttype->can_delete($managercontent));
203 $this->assertTrue($this->contenttype->can_delete($usercontent));
205 // Unassign capability to manager role and check not can only delete their own records.
206 unassign_capability('moodle/contentbank:deleteanycontent', $this->managerroleid);
207 $this->assertTrue($this->contenttype->can_delete($managercontent));
208 $this->assertFalse($this->contenttype->can_delete($usercontent));
209 $this->setUser($this->manager2);
210 $this->assertFalse($this->contenttype->can_delete($managercontent));
211 $this->assertFalse($this->contenttype->can_delete($usercontent));
215 * Test the behaviour of delete_content().
217 public function test_delete_content() {
220 $this->resetAfterTest();
221 $this->contenttype_setup_scenario_data();
223 // Check the content has been created as expected.
224 $this->assertEquals(4, $DB->count_records('contentbank_content'));
226 // Check the content is deleted as expected.
227 $this->setUser($this->manager1);
228 $content = array_shift($this->contents[$this->manager1->id]);
229 $deleted = $this->contenttype->delete_content($content);
230 $this->assertTrue($deleted);
231 $this->assertEquals(3, $DB->count_records('contentbank_content'));
235 * Helper function to setup 3 users (manager1, manager2 and user) and 4 contents (3 created by manager1 and 1 by user).
237 protected function contenttype_setup_scenario_data(): void {
239 $systemcontext = context_system::instance();
242 $this->manager1 = $this->getDataGenerator()->create_user();
243 $this->manager2 = $this->getDataGenerator()->create_user();
244 $this->managerroleid = $DB->get_field('role', 'id', array('shortname' => 'manager'));
245 $this->getDataGenerator()->role_assign($this->managerroleid, $this->manager1->id);
246 $this->getDataGenerator()->role_assign($this->managerroleid, $this->manager2->id);
247 $this->user = $this->getDataGenerator()->create_user();
249 // Add some content to the content bank.
250 $generator = $this->getDataGenerator()->get_plugin_generator('core_contentbank');
251 $this->contents[$this->manager1->id] = $generator->generate_contentbank_data(null, 3, $this->manager1->id);
252 $this->contents[$this->user->id] = $generator->generate_contentbank_data(null, 1, $this->user->id);
254 $this->contenttype = new \contenttype_testable\contenttype($systemcontext);
258 * Data provider for test_rename_content.
262 public function rename_content_provider() {
264 'Standard name' => ['New name', 'New name'],
265 'Name with digits' => ['Today is 17/04/2017', 'Today is 17/04/2017'],
266 'Name with symbols' => ['Follow us: @moodle', 'Follow us: @moodle'],
267 'Name with tags' => ['This is <b>bold</b>', 'This is bold'],
268 'Long name' => [str_repeat('a', 100), str_repeat('a', 100)],
269 'Too long name' => [str_repeat('a', 300), str_repeat('a', 255)]
274 * Test the behaviour of rename_content().
276 * @dataProvider rename_content_provider
277 * @param string $newname The name to set
278 * @param string $expected The name result
280 * @covers ::rename_content
282 public function test_rename_content(string $newname, string $expected) {
285 $this->resetAfterTest();
287 // Create course and teacher user.
288 $course = $this->getDataGenerator()->create_course();
289 $teacher = $this->getDataGenerator()->create_and_enrol($course, 'editingteacher');
290 $coursecontext = \context_course::instance($course->id);
291 $contenttype = new contenttype($coursecontext);
293 // Add some content to the content bank as teacher.
294 $this->setUser($teacher);
295 $generator = $this->getDataGenerator()->get_plugin_generator('core_contentbank');
296 $contents = $generator->generate_contentbank_data('contenttype_testable', 1, $teacher->id);
297 $content = array_shift($contents);
299 $oldname = $content->get_name();
301 // Check the content is renamed as expected by a user with permission.
302 $renamed = $contenttype->rename_content($content, $newname);
303 $this->assertTrue($renamed);
304 $record = $DB->get_record('contentbank_content', ['id' => $content->get_id()]);
305 $this->assertNotEquals($oldname, $record->name);
306 $this->assertEquals($expected, $record->name);
310 * Test the behaviour of can_manage().
312 * @covers ::can_manage
314 public function test_can_manage() {
317 $this->resetAfterTest();
318 $generator = $this->getDataGenerator()->get_plugin_generator('core_contentbank');
320 // Create course and teacher user.
321 $teacherroleid = $DB->get_field('role', 'id', ['shortname' => 'editingteacher']);
322 $course = $this->getDataGenerator()->create_course();
323 $teacher = $this->getDataGenerator()->create_and_enrol($course, 'editingteacher');
324 $manager = $this->getDataGenerator()->create_and_enrol($course, 'manager');
325 $coursecontext = \context_course::instance($course->id);
327 $contenttype = new contenttype($coursecontext);
329 // Add some content to the content bank as admin.
330 $this->setAdminUser();
331 $contentsbyadmin = $generator->generate_contentbank_data('contenttype_testable', 1, $USER->id, $coursecontext);
332 $contentbyadmin = array_shift($contentsbyadmin);
334 // Add some content to the content bank as teacher.
335 $contentsbyteacher = $generator->generate_contentbank_data('contenttype_testable', 1, $teacher->id, $coursecontext);
336 $contentbyteacher = array_shift($contentsbyteacher);
338 // Check the content has been created as expected.
339 $records = $DB->count_records('contentbank_content');
340 $this->assertEquals(2, $records);
342 // Check manager can manage by default all the contents created.
343 $this->setUser($manager);
344 $this->assertTrue($contenttype->can_manage($contentbyteacher));
345 $this->assertTrue($contenttype->can_manage($contentbyadmin));
347 // Check teacher can only edit their own content.
348 $this->setUser($teacher);
349 $this->assertTrue($contenttype->can_manage($contentbyteacher));
350 $this->assertFalse($contenttype->can_manage($contentbyadmin));
352 // Unassign capability to teacher role and check they not can not edit any content.
353 unassign_capability('moodle/contentbank:manageowncontent', $teacherroleid);
354 $this->assertFalse($contenttype->can_manage($contentbyteacher));
355 $this->assertFalse($contenttype->can_manage($contentbyadmin));