MDL-68819 core_contentbank: "Upload" button is not localized.
[moodle.git] / contentbank / tests / contenttype_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/>.
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  */
26 namespace core_contentbank;
28 use stdClass;
29 use context_system;
30 use 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  */
41 class core_contenttype_contenttype_testcase extends \advanced_testcase {
43     /** @var int Identifier for the manager role. */
44     protected $managerroleid;
46     /** @var stdClass Manager user. */
47     protected $manager1;
49     /** @var stdClass Manager user. */
50     protected $manager2;
52     /** @var stdClass User. */
53     protected $user;
55     /** @var array List of contents created (every user has a key with contents created by her). */
56     protected $contents = [];
58     /** @var contenttype The contenttype instance. */
59     protected $contenttype;
61     /**
62      * Setup to ensure that fixtures are loaded.
63      */
64     public static function setupBeforeClass(): void {
65         global $CFG;
67         require_once($CFG->dirroot . '/contentbank/tests/fixtures/testable_contenttype.php');
68         require_once($CFG->dirroot . '/contentbank/tests/fixtures/testable_content.php');
69     }
71     /**
72      * Tests get_contenttype_name result.
73      *
74      * @covers ::get_contenttype_name
75      */
76     public function test_get_contenttype_name() {
77         $this->resetAfterTest();
79         $systemcontext = \context_system::instance();
80         $testable = new contenttype($systemcontext);
82         $this->assertEquals('contenttype_testable', $testable->get_contenttype_name());
83     }
85     /**
86      * Tests get_plugin_name result.
87      *
88      * @covers ::get_plugin_name
89      */
90     public function test_get_plugin_name() {
91         $this->resetAfterTest();
93         $systemcontext = \context_system::instance();
94         $testable = new contenttype($systemcontext);
96         $this->assertEquals('testable', $testable->get_plugin_name());
97     }
99     /**
100      * Tests get_icon result.
101      *
102      * @covers ::get_icon
103      */
104     public function test_get_icon() {
105         $this->resetAfterTest();
107         $systemcontext = \context_system::instance();
108         $testable = new contenttype($systemcontext);
109         $record = new stdClass();
110         $record->name = 'New content';
111         $content = $testable->create_content($record);
112         $icon = $testable->get_icon($content);
113         $this->assertContains('archive', $icon);
114     }
116     /**
117      * Tests is_feature_supported behavior .
118      *
119      * @covers ::is_feature_supported
120      */
121     public function test_is_feature_supported() {
122         $this->resetAfterTest();
124         $systemcontext = \context_system::instance();
125         $testable = new contenttype($systemcontext);
127         $this->assertTrue($testable->is_feature_supported(contenttype::CAN_TEST));
128         $this->assertFalse($testable->is_feature_supported(contenttype::CAN_UPLOAD));
129     }
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();
139         $systemcontext = \context_system::instance();
140         $testable = new contenttype($systemcontext);
142         $this->setAdminUser();
143         $this->assertFalse($testable->is_feature_supported(contenttype::CAN_UPLOAD));
144         $this->assertFalse($testable->can_upload());
145     }
147     /**
148      * Test create_content() with empty data.
149      *
150      * @covers ::create_content
151      */
152     public function test_create_empty_content() {
153         $this->resetAfterTest();
155         // Create empty content.
156         $record = new stdClass();
158         $contenttype = new contenttype(context_system::instance());
159         $content = $contenttype->create_content($record);
161         $this->assertEquals('contenttype_testable', $content->get_content_type());
162         $this->assertInstanceOf('\\contenttype_testable\\content', $content);
163     }
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();
173         // Create content.
174         $record = new stdClass();
175         $record->name = 'Test content';
176         $record->configdata = '';
177         $record->contenttype = '';
179         $contenttype = new contenttype(context_system::instance());
180         $content = $contenttype->create_content($record);
182         $this->assertEquals('contenttype_testable', $content->get_content_type());
183         $this->assertInstanceOf('\\contenttype_testable\\content', $content);
184     }
186     /**
187      * Test the behaviour of can_delete().
188      */
189     public function test_can_delete() {
190         global $DB;
192         $this->resetAfterTest();
193         $this->contenttype_setup_scenario_data();
195         $managercontent = array_shift($this->contents[$this->manager1->id]);
196         $usercontent = array_shift($this->contents[$this->user->id]);
198         // Check the content has been created as expected.
199         $records = $DB->count_records('contentbank_content');
200         $this->assertEquals(4, $records);
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));
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));
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     }
221     /**
222      * Test the behaviour of delete_content().
223      */
224     public function test_delete_content() {
225         global $DB;
227         $this->resetAfterTest();
228         $this->contenttype_setup_scenario_data();
230         // Check the content has been created as expected.
231         $this->assertEquals(4, $DB->count_records('contentbank_content'));
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     }
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();
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();
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);
261         $this->contenttype = new \contenttype_testable\contenttype($systemcontext);
262     }
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     }
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;
292         $this->resetAfterTest();
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);
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);
306         $oldname = $content->get_name();
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     }
316     /**
317      * Test the behaviour of move_content().
318      */
319     public function test_move_content() {
320         global $DB;
322         $this->resetAfterTest();
323         $systemcontext = context_system::instance();
324         $course = $this->getDataGenerator()->create_course();
325         $coursecontext = \context_course::instance($course->id);
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);
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]));
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]));
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]));
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     }
356     /**
357      * Test the behaviour of can_manage().
358      *
359      * @covers ::can_manage
360      */
361     public function test_can_manage() {
362         global $DB, $USER;
364         $this->resetAfterTest();
365         $generator = $this->getDataGenerator()->get_plugin_generator('core_contentbank');
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);
374         $contenttype = new contenttype($coursecontext);
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);
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);
385         // Check the content has been created as expected.
386         $records = $DB->count_records('contentbank_content');
387         $this->assertEquals(2, $records);
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));
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));
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     }