From 3a6ca392d844d6f652682364e83d716db813598e Mon Sep 17 00:00:00 2001 From: Amaia Anabitarte Date: Fri, 17 Apr 2020 13:40:33 +0200 Subject: [PATCH] MDL-67790 core_contentbank: Unit and behat tests for renaming content --- .../h5p/tests/behat/manage_content.feature | 47 ++++++ .../h5p/tests/content_h5p_test.php | 4 +- contentbank/tests/content_test.php | 49 ++++++ contentbank/tests/contenttype_test.php | 102 ++++++++++++- .../tests/external/rename_content_test.php | 140 ++++++++++++++++++ 5 files changed, 339 insertions(+), 3 deletions(-) create mode 100644 contentbank/contenttype/h5p/tests/behat/manage_content.feature create mode 100644 contentbank/tests/external/rename_content_test.php diff --git a/contentbank/contenttype/h5p/tests/behat/manage_content.feature b/contentbank/contenttype/h5p/tests/behat/manage_content.feature new file mode 100644 index 00000000000..5705a9e358c --- /dev/null +++ b/contentbank/contenttype/h5p/tests/behat/manage_content.feature @@ -0,0 +1,47 @@ +@core @core_contentbank @contenttype_h5p @_file_upload @javascript +Feature: Manage H5P content from the content bank + In order to manage H5P content in the content bank + As an admin + I need to be able to edit any H5P content in the content bank + + Background: + Given the following "users" exist: + | username | firstname | lastname | email | + | teacher1 | Teacher | 1 | teacher1@example.com | + And the following "courses" exist: + | fullname | shortname | category | + | Course 1 | C1 | 0 | + And the following "course enrolments" exist: + | user | course | role | + | teacher1 | C1 | editingteacher | + And the following "contentbank content" exist: + | course| contenttype | user | contentname | + | C1 | contenttype_h5p | admin | filltheblanks.h5p | + | C1 | contenttype_h5p | teacher1 | ipsums.h5p | + And I log in as "admin" + And I am on "Course 1" course homepage with editing mode on + And I add the "Navigation" block if not present + And I log out + + Scenario: Teachers can rename their own content in the content bank + Given I log in as "teacher1" + And I am on "Course 1" course homepage + And I expand "Site pages" node + And I click on "Content bank" "link" + And I follow "ipsums.h5p" + When I open the action menu in "region-main-settings-menu" "region" + And I should see "Rename" + And I choose "Rename" in the open action menu + And I set the field "Content name" to "New name" + And I click on "Rename" "button" + And I wait until the page is ready + Then I should not see "ipsums.h5p" + And I should see "New name" + + Scenario: Teachers can't rename content created by other users in the content bank + Given I log in as "teacher1" + And I am on "Course 1" course homepage + And I expand "Site pages" node + And I click on "Content bank" "link" + When I follow "filltheblanks.h5p" + Then "region-main-settings-menu" "region" should not exist diff --git a/contentbank/contenttype/h5p/tests/content_h5p_test.php b/contentbank/contenttype/h5p/tests/content_h5p_test.php index a4082f84e07..657a459d768 100644 --- a/contentbank/contenttype/h5p/tests/content_h5p_test.php +++ b/contentbank/contenttype/h5p/tests/content_h5p_test.php @@ -51,14 +51,14 @@ class contenttype_h5p_content_plugin_testcase extends advanced_testcase { // Create a dummy file. $filename = 'content.h5p'; - $dummy = array( + $dummy = [ 'contextid' => \context_system::instance()->id, 'component' => 'contentbank', 'filearea' => 'public', 'itemid' => $content->get_id(), 'filepath' => '/', 'filename' => $filename - ); + ]; $fs = get_file_storage(); $fs->create_file_from_string($dummy, 'dummy content'); diff --git a/contentbank/tests/content_test.php b/contentbank/tests/content_test.php index 04b722f90c9..2fcd66c67b2 100644 --- a/contentbank/tests/content_test.php +++ b/contentbank/tests/content_test.php @@ -64,6 +64,55 @@ class core_contenttype_content_testcase extends \advanced_testcase { $this->assertEquals($record->name, $content->get_name()); } + /** + * Data provider for test_set_name. + * + * @return array + */ + public function set_name_provider() { + return [ + 'Standard name' => ['New name', 'New name'], + 'Name with digits' => ['Today is 17/04/2017', 'Today is 17/04/2017'], + 'Name with symbols' => ['Follow us: @moodle', 'Follow us: @moodle'], + 'Name with tags' => ['This is bold', 'This is bold'], + 'Long name' => [str_repeat('a', 100), str_repeat('a', 100)], + 'Too long name' => [str_repeat('a', 300), str_repeat('a', 255)] + ]; + } + + /** + * Tests for 'set_name' behaviour. + * + * @dataProvider set_name_provider + * @param string $newname The name to set + * @param string $expected The name result + * + * @covers ::set_name + */ + public function test_set_name(string $newname, string $expected) { + global $DB; + + $this->resetAfterTest(); + $this->setAdminUser(); + + $oldname = "Old name"; + $context = context_system::instance(); + + // Create content. + $record = new stdClass(); + $record->name = $oldname; + + $contenttype = new contenttype($context); + $content = $contenttype->create_content($record); + $this->assertEquals($oldname, $content->get_name()); + + $content->set_name($newname); + $this->assertEquals($expected, $content->get_name()); + + $record = $DB->get_record('contentbank_content', ['id' => $content->get_id()]); + $this->assertEquals($expected, $record->name); + } + /** * Tests for behaviour of get_content_type(). * diff --git a/contentbank/tests/contenttype_test.php b/contentbank/tests/contenttype_test.php index 7175b6364a4..e74bd1bd9d2 100644 --- a/contentbank/tests/contenttype_test.php +++ b/contentbank/tests/contenttype_test.php @@ -176,7 +176,6 @@ class core_contenttype_contenttype_testcase extends \advanced_testcase { $this->assertInstanceOf('\\contenttype_testable\\content', $content); } - /** * Test the behaviour of can_delete(). */ @@ -254,4 +253,105 @@ class core_contenttype_contenttype_testcase extends \advanced_testcase { $this->contenttype = new \contenttype_testable\contenttype($systemcontext); } + + /** + * Data provider for test_rename_content. + * + * @return array + */ + public function rename_content_provider() { + return [ + 'Standard name' => ['New name', 'New name'], + 'Name with digits' => ['Today is 17/04/2017', 'Today is 17/04/2017'], + 'Name with symbols' => ['Follow us: @moodle', 'Follow us: @moodle'], + 'Name with tags' => ['This is bold', 'This is bold'], + 'Long name' => [str_repeat('a', 100), str_repeat('a', 100)], + 'Too long name' => [str_repeat('a', 300), str_repeat('a', 255)] + ]; + } + + /** + * Test the behaviour of rename_content(). + * + * @dataProvider rename_content_provider + * @param string $newname The name to set + * @param string $expected The name result + * + * @covers ::rename_content + */ + public function test_rename_content(string $newname, string $expected) { + global $DB; + + $this->resetAfterTest(); + + // Create course and teacher user. + $course = $this->getDataGenerator()->create_course(); + $teacher = $this->getDataGenerator()->create_and_enrol($course, 'editingteacher'); + $coursecontext = \context_course::instance($course->id); + $contenttype = new contenttype($coursecontext); + + // Add some content to the content bank as teacher. + $this->setUser($teacher); + $generator = $this->getDataGenerator()->get_plugin_generator('core_contentbank'); + $contents = $generator->generate_contentbank_data('contenttype_testable', 1, $teacher->id); + $content = array_shift($contents); + + $oldname = $content->get_name(); + + // Check the content is renamed as expected by a user with permission. + $renamed = $contenttype->rename_content($content, $newname); + $this->assertTrue($renamed); + $record = $DB->get_record('contentbank_content', ['id' => $content->get_id()]); + $this->assertNotEquals($oldname, $record->name); + $this->assertEquals($expected, $record->name); + } + + /** + * Test the behaviour of can_manage(). + * + * @covers ::can_manage + */ + public function test_can_manage() { + global $DB, $USER; + + $this->resetAfterTest(); + $generator = $this->getDataGenerator()->get_plugin_generator('core_contentbank'); + + // Create course and teacher user. + $teacherroleid = $DB->get_field('role', 'id', ['shortname' => 'editingteacher']); + $course = $this->getDataGenerator()->create_course(); + $teacher = $this->getDataGenerator()->create_and_enrol($course, 'editingteacher'); + $manager = $this->getDataGenerator()->create_and_enrol($course, 'manager'); + $coursecontext = \context_course::instance($course->id); + + $contenttype = new contenttype($coursecontext); + + // Add some content to the content bank as admin. + $this->setAdminUser(); + $contentsbyadmin = $generator->generate_contentbank_data('contenttype_testable', 1, $USER->id, $coursecontext); + $contentbyadmin = array_shift($contentsbyadmin); + + // Add some content to the content bank as teacher. + $contentsbyteacher = $generator->generate_contentbank_data('contenttype_testable', 1, $teacher->id, $coursecontext); + $contentbyteacher = array_shift($contentsbyteacher); + + // Check the content has been created as expected. + $records = $DB->count_records('contentbank_content'); + $this->assertEquals(2, $records); + + // Check manager can manage by default all the contents created. + $this->setUser($manager); + $this->assertTrue($contenttype->can_manage($contentbyteacher)); + $this->assertTrue($contenttype->can_manage($contentbyadmin)); + + // Check teacher can only edit their own content. + $this->setUser($teacher); + $this->assertTrue($contenttype->can_manage($contentbyteacher)); + $this->assertFalse($contenttype->can_manage($contentbyadmin)); + + // Unassign capability to teacher role and check they not can not edit any content. + unassign_capability('moodle/contentbank:manageowncontent', $teacherroleid); + $this->assertFalse($contenttype->can_manage($contentbyteacher)); + $this->assertFalse($contenttype->can_manage($contentbyadmin)); + } } diff --git a/contentbank/tests/external/rename_content_test.php b/contentbank/tests/external/rename_content_test.php new file mode 100644 index 00000000000..4b1bf6bb45e --- /dev/null +++ b/contentbank/tests/external/rename_content_test.php @@ -0,0 +1,140 @@ +. + +/** + * Core content bank external functions tests. + * + * @package core_contentbank + * @category external + * @copyright 2020 Sara Arjona + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + * @since Moodle 3.9 + */ + +namespace core_contentbank; + +defined('MOODLE_INTERNAL') || die(); + +global $CFG; +require_once($CFG->dirroot . '/contentbank/tests/fixtures/testable_contenttype.php'); +require_once($CFG->dirroot . '/contentbank/tests/fixtures/testable_content.php'); +require_once($CFG->dirroot . '/webservice/tests/helpers.php'); + +use core_contentbank\external\delete_content; +use core_contentbank\external\external; +use core_contentbank\external\rename_content; +use external_api; + +/** + * Core content bank external functions tests. + * + * @package core_contentbank + * @copyright 2020 Sara Arjona + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + * @coversDefaultClass \core_contentbank\external + */ +class rename_content_testcase extends \externallib_advanced_testcase { + + /** + * Data provider for test_rename_content. + * + * @return array + */ + public function rename_content_provider() { + return [ + 'Standard name' => ['New name', 'New name'], + 'Name with digits' => ['Today is 17/04/2017', 'Today is 17/04/2017'], + 'Name with symbols' => ['Follow us: @moodle', 'Follow us: @moodle'], + 'Name with tags' => ['This is bold', 'This is bold'], + 'Long name' => [str_repeat('a', 100), str_repeat('a', 100)], + 'Too long name' => [str_repeat('a', 300), str_repeat('a', 255)] + ]; + } + + /** + * Test the behaviour of rename_content() for users with permission. + * + * @dataProvider rename_content_provider + * @param string $newname The name to set + * @param string $expected The name result + * + * @covers ::execute + */ + public function test_rename_content_with_permission(string $newname, string $expected) { + global $DB; + $this->resetAfterTest(); + + // Create users. + $roleid = $DB->get_field('role', 'id', ['shortname' => 'editingteacher']); + $teacher = $this->getDataGenerator()->create_user(); + + $this->getDataGenerator()->role_assign($roleid, $teacher->id); + $this->setUser($teacher); + + // Add some content to the content bank as teacher. + $generator = $this->getDataGenerator()->get_plugin_generator('core_contentbank'); + $contents = $generator->generate_contentbank_data('contenttype_testable', 1, $teacher->id); + $content = array_shift($contents); + + $oldname = $content->get_name(); + + // Call the WS and check the content is renamed as expected. + $result = rename_content::execute($content->get_id(), $newname); + $result = external_api::clean_returnvalue(rename_content::execute_returns(), $result); + $this->assertTrue($result['result']); + $record = $DB->get_record('contentbank_content', ['id' => $content->get_id()]); + $this->assertNotEquals($oldname, $record->name); + $this->assertEquals($expected, $record->name); + + // Call the WS using an unexisting contentid and check an error is thrown. + $this->expectException(\invalid_response_exception::class); + $result = rename_content::execute_returns($content->get_id() + 1, $oldname); + $result = external_api::clean_returnvalue(rename_content::execute_returns(), $result); + $this->assertFalse($result['result']); + } + + /** + * Test the behaviour of rename_content() for users with permission. + * + * @covers ::execute + */ + public function test_rename_content_without_permission() { + global $DB; + $this->resetAfterTest(); + + // Create users. + $course = $this->getDataGenerator()->create_course(); + $teacher = $this->getDataGenerator()->create_and_enrol($course, 'editingteacher'); + $student = $this->getDataGenerator()->create_and_enrol($course, 'student'); + + // Add some content to the content bank as teacher. + $generator = $this->getDataGenerator()->get_plugin_generator('core_contentbank'); + $contents = $generator->generate_contentbank_data('contenttype_testable', 1, $teacher->id); + $content = array_shift($contents); + + $oldname = $content->get_name(); + $newname = 'New name'; + + // Call the WS and check the content has not been renamed by the student. + $this->setUser($student); + $result = rename_content::execute($content->get_id(), $newname); + $result = external_api::clean_returnvalue(rename_content::execute_returns(), $result); + $this->assertFalse($result['result']); + $record = $DB->get_record('contentbank_content', ['id' => $content->get_id()]); + $this->assertEquals($oldname, $record->name); + $this->assertNotEquals($newname, $record->name); + } +} -- 2.43.0