<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
< /**
< * Content bank repository browser unit tests.
< *
< * @package repository_contentbank
< * @copyright 2020 Mihail Geshoski <mihail@moodle.com>
< * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
< */
> namespace repository_contentbank;
defined('MOODLE_INTERNAL') || die();
global $CFG;
require_once("$CFG->dirroot/repository/lib.php");
/**
* Tests for the content bank browser class.
*
* @package repository_contentbank
* @copyright 2020 Mihail Geshoski <mihail@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
< class repository_contentbank_browser_testcase extends advanced_testcase {
> class browser_test extends \advanced_testcase {
/**
* Test get_content() in the system context with users that have capability to access/view content bank content
* within the system context. By default, every authenticated user should be able to access/view the content in
* the system context.
*/
public function test_get_content_system_context_user_has_capabilities() {
< global $DB;
> global $DB, $CFG;
$this->resetAfterTest(true);
$systemcontext = \context_system::instance();
// Create a course category $coursecategory.
$coursecategory = $this->getDataGenerator()->create_category(['name' => 'Category']);
$coursecatcontext = \context_coursecat::instance($coursecategory->id);
// Get the default 'Miscellaneous' category.
$miscellaneouscat = \core_course_category::get(1);
$miscellaneouscatcontext = \context_coursecat::instance($miscellaneouscat->id);
// Create course.
$course = $this->getDataGenerator()->create_course(['category' => $coursecategory->id]);
$admin = get_admin();
// Create a user (not enrolled in a course).
$user = $this->getDataGenerator()->create_user();
// Add some content to the content bank.
$generator = $this->getDataGenerator()->get_plugin_generator('core_contentbank');
// Add some content bank files in the system context.
> $filepath = $CFG->dirroot . '/h5p/tests/fixtures/filltheblanks.h5p';
$contentbankcontents = $generator->generate_contentbank_data('contenttype_h5p', 3, $admin->id,
< $systemcontext, true);
> $systemcontext, true, $filepath);
// Log in as admin.
$this->setUser($admin);
// Get the content bank nodes displayed to the admin in the system context.
$browser = new \repository_contentbank\browser\contentbank_browser_context_system($systemcontext);
$repositorycontentnodes = $browser->get_content();
// All content nodes should be available to the admin user.
// There should be a total of 5 nodes, 3 file nodes representing the existing content bank files in the
// system context and 2 folder nodes representing the default course category 'Miscellaneous' and 'Category'.
$this->assertCount(5, $repositorycontentnodes);
$contextfolders = [
[
'name' => 'Miscellaneous',
'contextid' => $miscellaneouscatcontext->id
],
[
'name' => 'Category',
'contextid' => $coursecatcontext->id
]
];
$expected = $this->generate_expected_content($contextfolders, $contentbankcontents);
$this->assertEqualsCanonicalizing($expected, $repositorycontentnodes);
// Log in as a user.
$this->setUser($user);
// Get the content bank nodes displayed to an authenticated user in the system context.
$browser = new \repository_contentbank\browser\contentbank_browser_context_system($systemcontext);
$repositorycontentnodes = $browser->get_content();
// There should be 3 nodes representing the existing content bank files in the system context.
// The course category context folder node should be ignored as the user does not have an access to
// the content of the category's courses.
$this->assertCount(3, $repositorycontentnodes);
$expected = $this->generate_expected_content([], $contentbankcontents);
$this->assertEqualsCanonicalizing($expected, $repositorycontentnodes);
// Enrol the user as an editing teacher in the course.
$editingteacherrole = $DB->get_field('role', 'id', ['shortname' => 'editingteacher']);
$this->getDataGenerator()->enrol_user($user->id, $course->id, $editingteacherrole);
// Get the content bank nodes displayed to the editing teacher in the system context.
$browser = new \repository_contentbank\browser\contentbank_browser_context_system($systemcontext);
$repositorycontentnodes = $browser->get_content();
// All content nodes should now be available to the editing teacher.
// There should be a total of 4 nodes, 3 file nodes representing the existing content bank files in the
// system context and 1 folder node representing the course category 'Category' (The editing teacher is now
// enrolled in a course from the category).
$this->assertCount(4, $repositorycontentnodes);
$contextfolders = [
[
'name' => 'Category',
'contextid' => $coursecatcontext->id
]
];
$expected = $this->generate_expected_content($contextfolders, $contentbankcontents);
$this->assertEqualsCanonicalizing($expected, $repositorycontentnodes);
}
/**
* Test get_content() in the system context with users that do not have a capability to access/view content bank
* content within the system context. By default, every non-authenticated user should not be able to access/view
* the content in the system context.
*/
public function test_get_content_system_context_user_missing_capabilities() {
$this->resetAfterTest(true);
$systemcontext = \context_system::instance();
$admin = get_admin();
// Add some content to the content bank.
$generator = $this->getDataGenerator()->get_plugin_generator('core_contentbank');
// Add some content bank files in the system context.
$generator->generate_contentbank_data('contenttype_h5p', 3, $admin->id, $systemcontext, true);
// Log out.
$this->setUser();
// Get the content bank nodes displayed to a non-authenticated user in the system context.
$browser = new \repository_contentbank\browser\contentbank_browser_context_system($systemcontext);
$repositorycontents = $browser->get_content();
// Content nodes should not be available to the non-authenticated user in the system context.
$this->assertCount(0, $repositorycontents);
}
/**
* Test get_content() in the course category context with users that have capability to access/view content
* bank content within the course category context. By default, every authenticated user that has access to
* any category course should be able to access/view the content in the course category context.
*/
public function test_get_content_course_category_context_user_has_capabilities() {
> global $CFG;
$this->resetAfterTest(true);
>
// Create a course category.
$category = $this->getDataGenerator()->create_category(['name' => 'Category']);
$coursecatcontext = \context_coursecat::instance($category->id);
// Create course1.
$course1 = $this->getDataGenerator()->create_course(['fullname' => 'Course1', 'category' => $category->id]);
$course1context = \context_course::instance($course1->id);
// Create course2.
$course2 = $this->getDataGenerator()->create_course(['fullname' => 'Course2', 'category' => $category->id]);
$course2context = \context_course::instance($course2->id);
$admin = get_admin();
// Create editing teacher enrolled in course1.
$editingteacher = $this->getDataGenerator()->create_and_enrol($course1, 'editingteacher');
// Add some content to the content bank.
$generator = $this->getDataGenerator()->get_plugin_generator('core_contentbank');
// Add some content bank files in the course category context.
> $filepath = $CFG->dirroot . '/h5p/tests/fixtures/filltheblanks.h5p';
$contentbankcontents = $generator->generate_contentbank_data('contenttype_h5p', 3, $admin->id,
< $coursecatcontext, true);
> $coursecatcontext, true, $filepath);
$this->setUser($admin);
// Get the content bank nodes displayed to the admin in the course category context.
$browser = new \repository_contentbank\browser\contentbank_browser_context_coursecat($coursecatcontext);
$repositorycontents = $browser->get_content();
// All content nodes should be available to the admin user.
// There should be a total of 5 nodes, 3 file nodes representing the existing content bank files in the
// course category context and 2 folder nodes representing the courses 'Course1' and 'Course2'.
$this->assertCount(5, $repositorycontents);
$contextfolders = [
[
'name' => 'Course1',
'contextid' => $course1context->id
],
[
'name' => 'Course2',
'contextid' => $course2context->id
]
];
$expected = $this->generate_expected_content($contextfolders, $contentbankcontents);
$this->assertEqualsCanonicalizing($expected, $repositorycontents);
// Log in as an editing teacher enrolled in a child course.
$this->setUser($editingteacher);
// Get the content bank nodes displayed to the editing teacher in the course category context.
$browser = new \repository_contentbank\browser\contentbank_browser_context_coursecat($coursecatcontext);
$repositorycontents = $browser->get_content();
// There should be a total of 4 nodes, 3 file nodes representing the existing content bank files in the
// course category context and 1 folder node representing the course 'Course1' (The editing teacher is only
// enrolled in course1).
$this->assertCount(4, $repositorycontents);
$contextfolders = [
[
'name' => 'Course1',
'contextid' => $course1context->id
]
];
$expected = $this->generate_expected_content($contextfolders, $contentbankcontents);
$this->assertEqualsCanonicalizing($expected, $repositorycontents);
}
/**
* Test get_content() in the course category context with users that do not have capability to access/view content
* bank content within the course category context. By default, every non-authenticated user or authenticated users
* that cannot access/view course content from the course category should not be able to access/view the
* content in the course category context.
*/
public function test_get_content_course_category_context_user_missing_capabilities() {
$this->resetAfterTest(true);
// Create a course category 'Category'.
$category = $this->getDataGenerator()->create_category(['name' => 'Category']);
// Create course1 in 'Category'.
$course1 = $this->getDataGenerator()->create_course(['fullname' => 'Course1', 'category' => $category->id]);
// Create course2 in 'Miscellaneous' by default.
$course2 = $this->getDataGenerator()->create_course(['fullname' => 'Course2']);
// Create a teacher enrolled in course1.
$teacher = $this->getDataGenerator()->create_and_enrol($course1, 'teacher');
// Create an editing teacher enrolled in course2.
$editingteacher = $this->getDataGenerator()->create_and_enrol($course2, 'editingteacher');
$admin = get_admin();
// Add some content to the content bank.
$generator = $this->getDataGenerator()->get_plugin_generator('core_contentbank');
// Add some content bank files in the 'Category' context.
$coursecatcontext = \context_coursecat::instance($category->id);
$generator->generate_contentbank_data('contenttype_h5p', 3, $admin->id,
$coursecatcontext, true);
// Log in as a non-editing teacher.
$this->setUser($teacher);
// Get the content bank nodes displayed to a non-editing teacher in the 'Category' context.
$browser = new \repository_contentbank\browser\contentbank_browser_context_coursecat($coursecatcontext);
$repositorycontents = $browser->get_content();
// Content nodes should not be available to a non-editing teacher in the 'Category' context.
$this->assertCount(0, $repositorycontents);
// Log in as an editing teacher.
$this->setUser($editingteacher);
// Get the content bank nodes displayed to a an editing teacher in the 'Category' context.
$browser = new \repository_contentbank\browser\contentbank_browser_context_coursecat($coursecatcontext);
$repositorycontents = $browser->get_content();
// Content nodes should not be available to an editing teacher in the 'Category' context.
$this->assertCount(0, $repositorycontents);
// Log out.
$this->setUser();
// Get the content bank nodes displayed to a non-authenticated user in the course category context.
$browser = new \repository_contentbank\browser\contentbank_browser_context_coursecat($coursecatcontext);
$repositorycontents = $browser->get_content();
// Content nodes should not be available to the non-authenticated user in the course category context.
$this->assertCount(0, $repositorycontents);
}
/**
* Test get_content() in the course context with users that have capability to access/view content
* bank content within the course context. By default, admin, managers, course creators, editing teachers enrolled
* in the course should be able to access/view the content.
*/
public function test_get_content_course_context_user_has_capabilities() {
> global $CFG;
$this->resetAfterTest(true);
>
// Create course1.
$course = $this->getDataGenerator()->create_course(['fullname' => 'Course']);
$coursecontext = \context_course::instance($course->id);
$admin = get_admin();
// Create editing teacher enrolled in course.
$editingteacher = $this->getDataGenerator()->create_and_enrol($course, 'editingteacher');
// Add some content to the content bank.
$generator = $this->getDataGenerator()->get_plugin_generator('core_contentbank');
// Add some content bank files in the course context.
> $filepath = $CFG->dirroot . '/h5p/tests/fixtures/filltheblanks.h5p';
$contentbankcontents = $generator->generate_contentbank_data('contenttype_h5p', 3, $admin->id,
< $coursecontext, true);
> $coursecontext, true, $filepath);
$this->setUser($admin);
// Get the content bank nodes displayed to the admin in the course context.
$browser = new \repository_contentbank\browser\contentbank_browser_context_course($coursecontext);
$repositorycontents = $browser->get_content();
// All content nodes should be available to the admin user.
// There should be 3 file nodes representing the existing content bank files in the
// course context.
$this->assertCount(3, $repositorycontents);
$expected = $this->generate_expected_content([], $contentbankcontents);
$this->assertEqualsCanonicalizing($expected, $repositorycontents);
// Log in as an editing teacher.
$this->setUser($editingteacher);
// All content nodes should also be available to the editing teacher.
// Get the content bank nodes displayed to the editing teacher in the course context.
$browser = new \repository_contentbank\browser\contentbank_browser_context_course($coursecontext);
$repositorycontents = $browser->get_content();
// There should be 3 file nodes representing the existing content bank files in the
// course context.
$this->assertCount(3, $repositorycontents);
$expected = $this->generate_expected_content([], $contentbankcontents);
$this->assertEqualsCanonicalizing($expected, $repositorycontents);
}
/**
* Test get_content() in the course context with users that do not have capability to access/view content
* bank content within the course context. By default, every user which is not an admin, manager, course creator,
* editing teacher enrolled in the course should not be able to access/view the content.
*/
public function test_get_content_course_context_user_missing_capabilities() {
$this->resetAfterTest(true);
// Create course1.
$course1 = $this->getDataGenerator()->create_course(['fullname' => 'Course1']);
$course1context = \context_course::instance($course1->id);
// Create course2.
$course2 = $this->getDataGenerator()->create_course(['fullname' => 'Course2']);
$course2context = \context_course::instance($course2->id);
$admin = get_admin();
// Create non-editing teacher enrolled in course1.
$teacher = $this->getDataGenerator()->create_and_enrol($course1, 'teacher');
// Create editing teacher enrolled in course1.
$editingteacher = $this->getDataGenerator()->create_and_enrol($course1, 'editingteacher');
// Add some content to the content bank.
$generator = $this->getDataGenerator()->get_plugin_generator('core_contentbank');
// Add some content bank files in the course1 context.
$generator->generate_contentbank_data('contenttype_h5p', 2, $admin->id,
$course1context, true);
// Add some content bank files in the course2 context.
$generator->generate_contentbank_data('contenttype_h5p', 3, $admin->id,
$course2context, true);
// Log in as a non-editing teacher.
$this->setUser($teacher);
// Get the content bank nodes displayed to the non-editing teacher in the course1 context.
$browser = new \repository_contentbank\browser\contentbank_browser_context_course($course1context);
$repositorycontents = $browser->get_content();
// Content nodes should not be available to the teacher in the course1 context.
$this->assertCount(0, $repositorycontents);
// Log in as editing teacher.
$this->setUser($editingteacher);
// Get the content bank nodes displayed to the editing teacher in the course2 context.
$browser = new \repository_contentbank\browser\contentbank_browser_context_course($course2context);
$repositorycontents = $browser->get_content();
// Content nodes should not be available to the teacher in the course2 context. The editing teacher is not
// enrolled in this course.
$this->assertCount(0, $repositorycontents);
}
/**
* Test get_navigation() in the system context.
*/
public function test_get_navigation_system_context() {
$this->resetAfterTest(true);
$systemcontext = \context_system::instance();
$browser = new \repository_contentbank\browser\contentbank_browser_context_system($systemcontext);
$navigation = $browser->get_navigation();
// The navigation array should contain only 1 element, representing the system navigation node.
$this->assertCount(1, $navigation);
$expected = [
\repository_contentbank\helper::create_navigation_node($systemcontext)
];
$this->assertEquals($expected, $navigation);
}
/**
* Test get_navigation() in the course category context.
*/
public function test_get_navigation_course_category_context() {
$this->resetAfterTest(true);
$systemcontext = \context_system::instance();
// Create a course category.
$category = $this->getDataGenerator()->create_category(['name' => 'category']);
$categorycontext = \context_coursecat::instance($category->id);
// Create a course subcategory.
$subcategory = $this->getDataGenerator()->create_category(['name' => 'subcategory', 'parent' => $category->id]);
$subcategorytcontext = \context_coursecat::instance($subcategory->id);
// Get navigation nodes in the category context.
$browser = new \repository_contentbank\browser\contentbank_browser_context_coursecat($categorycontext);
$navigation = $browser->get_navigation();
// The navigation array should contain 2 elements, representing the system and course category
// navigation nodes.
$this->assertCount(2, $navigation);
$expected = [
\repository_contentbank\helper::create_navigation_node($systemcontext),
\repository_contentbank\helper::create_navigation_node($categorycontext)
];
$this->assertEquals($expected, $navigation);
// Get navigation nodes in the subcategory context.
$browser = new \repository_contentbank\browser\contentbank_browser_context_coursecat($subcategorytcontext);
$navigation = $browser->get_navigation();
// The navigation array should contain 3 elements, representing the system, category and subcategory
// navigation nodes.
$this->assertCount(3, $navigation);
$expected = [
\repository_contentbank\helper::create_navigation_node($systemcontext),
\repository_contentbank\helper::create_navigation_node($categorycontext),
\repository_contentbank\helper::create_navigation_node($subcategorytcontext)
];
$this->assertEquals($expected, $navigation);
}
/**
* Test get_navigation() in the course context.
*/
public function test_get_navigation_course_context() {
$this->resetAfterTest(true);
$systemcontext = \context_system::instance();
// Create a category.
$category = $this->getDataGenerator()->create_category(['name' => 'category']);
$categorycontext = \context_coursecat::instance($category->id);
// Create a subcategory.
$subcategory = $this->getDataGenerator()->create_category(['name' => 'category', 'parent' => $category->id]);
$subcategorycontext = \context_coursecat::instance($subcategory->id);
// Create a course in category.
$categorycourse = $this->getDataGenerator()->create_course(['category' => $category->id]);
$categorycoursecontext = \context_course::instance($categorycourse->id);
// Create a course in subcategory.
$subcategorycourse = $this->getDataGenerator()->create_course(['category' => $subcategory->id]);
$subcategorycoursecontext = \context_course::instance($subcategorycourse->id);
// Get navigation nodes in the category course context.
$browser = new \repository_contentbank\browser\contentbank_browser_context_course($categorycoursecontext);
$navigation = $browser->get_navigation();
// The navigation array should contain 3 elements, representing the system, category and course
// navigation nodes.
$this->assertCount(3, $navigation);
$expected = [
\repository_contentbank\helper::create_navigation_node($systemcontext),
\repository_contentbank\helper::create_navigation_node($categorycontext),
\repository_contentbank\helper::create_navigation_node($categorycoursecontext)
];
$this->assertEquals($expected, $navigation);
// Get navigation nodes in the subcategory course context.
$browser = new \repository_contentbank\browser\contentbank_browser_context_course($subcategorycoursecontext);
$navigation = $browser->get_navigation();
// The navigation array should contain 4 elements, representing the system, category, subcategory and
// subcategory course navigation nodes.
$this->assertCount(4, $navigation);
$expected = [
\repository_contentbank\helper::create_navigation_node($systemcontext),
\repository_contentbank\helper::create_navigation_node($categorycontext),
\repository_contentbank\helper::create_navigation_node($subcategorycontext),
\repository_contentbank\helper::create_navigation_node($subcategorycoursecontext)
];
$this->assertEquals($expected, $navigation);
}
/**
* Generate the expected array of content bank nodes.
*
* @param array $contextfolders The array containing the expected folder nodes
* @param array $contentbankcontents The array containing the expected contents
* @return array[] The expected array of content bank nodes
*/
private function generate_expected_content(array $contextfolders = [], array $contentbankcontents = []): array {
$expected = [];
if (!empty($contextfolders)) {
foreach ($contextfolders as $contextfolder) {
$expected[] = \repository_contentbank\helper::create_context_folder_node($contextfolder['name'],
base64_encode(json_encode(['contextid' => $contextfolder['contextid']])));
}
}
if (!empty($contentbankcontents)) {
foreach ($contentbankcontents as $content) {
$expected[] = \repository_contentbank\helper::create_contentbank_content_node($content);
}
}
return $expected;
}
}