MDL-86660 course_format: Display restricted activities in Overview
This commit is contained in:
@@ -0,0 +1,7 @@
|
||||
issueNumber: MDL-86660
|
||||
notes:
|
||||
core_courseformat:
|
||||
- message: >-
|
||||
The `$cm` attribute in `activityoverviewbase` has been updated to public
|
||||
visibility, allowing direct access to the course module instance
|
||||
type: changed
|
||||
@@ -0,0 +1,8 @@
|
||||
issueNumber: MDL-86660
|
||||
notes:
|
||||
core_courseformat:
|
||||
- message: >-
|
||||
A new `available` attribute has been added to `activityname_exporter`
|
||||
class. It allows the external API to return the activity's availability
|
||||
status relative to the current user.
|
||||
type: changed
|
||||
@@ -0,0 +1,9 @@
|
||||
issueNumber: MDL-86660
|
||||
notes:
|
||||
core_courseformat:
|
||||
- message: >-
|
||||
Two new public static methods have been added to the `overviewtable`
|
||||
class:
|
||||
- `is_cm_displayable`: Determines if a course module should be listed in the overview table.
|
||||
- `is_cm_available`: Checks if a course module is accessible to the user (and should therefore be rendered as a link).
|
||||
type: changed
|
||||
@@ -75,7 +75,7 @@ abstract class activityoverviewbase {
|
||||
*/
|
||||
public function __construct(
|
||||
/** @var cm_info The course module. */
|
||||
protected readonly cm_info $cm,
|
||||
public readonly cm_info $cm,
|
||||
) {
|
||||
$this->context = $cm->context;
|
||||
$this->course = $cm->get_course();
|
||||
|
||||
@@ -87,6 +87,11 @@ class activityname_exporter extends exporter {
|
||||
'multiple' => true,
|
||||
'default' => [],
|
||||
],
|
||||
'available' => [
|
||||
'type' => PARAM_BOOL,
|
||||
'null' => NULL_NOT_ALLOWED,
|
||||
'description' => 'Whether the activity is available.',
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
@@ -102,6 +107,7 @@ class activityname_exporter extends exporter {
|
||||
'hidden' => $templatedata->hidden,
|
||||
'stealth' => $templatedata->stealth,
|
||||
'sectiontitle' => $templatedata->sectiontitle ?? null,
|
||||
'available' => $templatedata->available,
|
||||
'errormessages' => $source->get_error_messages(),
|
||||
];
|
||||
}
|
||||
|
||||
@@ -75,6 +75,7 @@ class activityname implements externable, named_templatable, renderable {
|
||||
'hidden' => empty($cm->visible),
|
||||
'stealth' => $cm->is_stealth(),
|
||||
'nogroupserror' => $this->nogroupserror,
|
||||
'available' => overviewtable::is_cm_available($cm),
|
||||
];
|
||||
if ($format->uses_sections() && $section->uservisible) {
|
||||
$result->sectiontitle = $format->get_section_name($section);
|
||||
|
||||
@@ -92,9 +92,7 @@ class overviewpage implements renderable, named_templatable {
|
||||
$archetypes = [];
|
||||
|
||||
foreach ($modinfo->cms as $cm) {
|
||||
// Exclude activities that aren't visible or have no view link (e.g. label).
|
||||
// Account for folder being displayed inline.
|
||||
if (!$cm->uservisible || (!$cm->has_view() && strcmp($cm->modname, 'folder') !== 0)) {
|
||||
if (!overviewtable::is_cm_displayable($cm)) {
|
||||
continue;
|
||||
}
|
||||
if (array_key_exists($cm->modname, $modfullnames)) {
|
||||
|
||||
@@ -138,7 +138,7 @@ class overviewtable implements externable, named_templatable, renderable {
|
||||
private function load_all_overviews_from_each_activity(): array {
|
||||
$result = [];
|
||||
foreach ($this->get_related_course_modules() as $cm) {
|
||||
if (!$this->is_cm_displayable($cm)) {
|
||||
if (!self::is_cm_displayable($cm)) {
|
||||
continue;
|
||||
}
|
||||
$overview = overviewfactory::create($cm);
|
||||
@@ -215,13 +215,31 @@ class overviewtable implements externable, named_templatable, renderable {
|
||||
/**
|
||||
* Check if the course module is displayable in the overview table.
|
||||
*
|
||||
* @param cm_info $cm
|
||||
* @return bool
|
||||
* @param cm_info $cm The course module info
|
||||
* @return bool Whether the course module is displayable in the overview table or not.
|
||||
*/
|
||||
private function is_cm_displayable(cm_info $cm): bool {
|
||||
public static function is_cm_displayable(cm_info $cm): bool {
|
||||
// Exclude activities that aren't displayed in the course page (except for stealth),
|
||||
// activities that are not available but availability is hidden
|
||||
// or activities that have no view link (e.g. label).
|
||||
// Folder is an exception because it has settings to be displayed in the course
|
||||
// page without having a view link.
|
||||
return $cm->uservisible && ($cm->has_view() || strcmp($cm->modname, 'folder') === 0);
|
||||
return (
|
||||
(has_capability('moodle/course:viewhiddenactivities', $cm->context)
|
||||
|| (($cm->is_visible_on_course_page() || $cm->is_stealth())
|
||||
&& ($cm->available || !empty($cm->availableinfo))))
|
||||
&& ($cm->has_view() || strcmp($cm->modname, 'folder') === 0)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the given course module is available (so linkable) in the overview table.
|
||||
*
|
||||
* @param cm_info $cm The course module info
|
||||
* @return bool Whether the course module is available or not.
|
||||
*/
|
||||
public static function is_cm_available(cm_info $cm): bool {
|
||||
return $cm->uservisible || $cm->available;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -263,6 +281,13 @@ class overviewtable implements externable, named_templatable, renderable {
|
||||
return ['name' => $overview->get_name_overview()];
|
||||
}
|
||||
|
||||
if (!self::is_cm_available($overview->cm)) {
|
||||
return [
|
||||
'name' => $overview->get_name_overview(),
|
||||
'duedate' => $overview->get_due_date_overview(),
|
||||
];
|
||||
}
|
||||
|
||||
$row = [
|
||||
'name' => $overview->get_name_overview(),
|
||||
'duedate' => $overview->get_due_date_overview(),
|
||||
|
||||
@@ -26,12 +26,14 @@
|
||||
"sectiontitle": "Section title",
|
||||
"visible": true,
|
||||
"stealth": false,
|
||||
"nogroupserror": false
|
||||
"nogroupserror": false,
|
||||
"available": true
|
||||
}
|
||||
}}
|
||||
<div class="d-flex flex-column">
|
||||
<div class="fw-bold">
|
||||
<a href="{{activityurl}}" class="activityname">{{{activityname}}}</a>
|
||||
{{#available}}<a href="{{activityurl}}" class="activityname">{{{activityname}}}</a>{{/available}}
|
||||
{{^available}}<span class="activityname">{{{activityname}}}</span>{{/available}}
|
||||
</div>
|
||||
{{#sectiontitle}}
|
||||
<div class="small">
|
||||
|
||||
@@ -16,6 +16,8 @@
|
||||
|
||||
namespace core_courseformat\external;
|
||||
|
||||
use core_courseformat\output\local\overview\overviewtable;
|
||||
|
||||
/**
|
||||
* Tests for activityname_exporter.
|
||||
*
|
||||
@@ -57,7 +59,8 @@ final class activityname_exporter_test extends \advanced_testcase {
|
||||
$this->assertObjectHasProperty('stealth', $data);
|
||||
$this->assertObjectHasProperty('sectiontitle', $data);
|
||||
$this->assertObjectHasProperty('errormessages', $data);
|
||||
$this->assertCount(6, get_object_vars($data));
|
||||
$this->assertObjectHasProperty('available', $data);
|
||||
$this->assertCount(7, get_object_vars($data));
|
||||
|
||||
$expected = [
|
||||
'activityname' => \core_external\util::format_string($cm->name, $cm->context, true),
|
||||
@@ -66,6 +69,7 @@ final class activityname_exporter_test extends \advanced_testcase {
|
||||
'stealth' => $cm->is_stealth(),
|
||||
'sectiontitle' => $format->get_section_name($cm->get_section_info()),
|
||||
'errormessages' => [],
|
||||
'available' => overviewtable::is_cm_available($cm),
|
||||
];
|
||||
|
||||
foreach ($expected as $property => $value) {
|
||||
|
||||
@@ -28,8 +28,15 @@ namespace core_courseformat\output\local\overview;
|
||||
final class overviewtable_test extends \advanced_testcase {
|
||||
/**
|
||||
* Test export_for_external method.
|
||||
*
|
||||
* @param string $role The role of the user.
|
||||
* @param int $expectedactivities The expected number of activities visible to the user.
|
||||
*/
|
||||
public function test_export_for_external(): void {
|
||||
#[\PHPUnit\Framework\Attributes\DataProvider('provider_export_for_external')]
|
||||
public function test_export_for_external(
|
||||
string $role,
|
||||
int $expectedactivities,
|
||||
): void {
|
||||
$this->resetAfterTest();
|
||||
|
||||
$course = $this->getDataGenerator()->create_course();
|
||||
@@ -37,32 +44,49 @@ final class overviewtable_test extends \advanced_testcase {
|
||||
// Ensure the course is fully loaded.
|
||||
$course = get_course($course->id);
|
||||
|
||||
// Create three pages, one of them unavailable and hidden to students.
|
||||
$mods = [
|
||||
'assign1' => $this->getDataGenerator()->create_module('assign', ['course' => $course->id]),
|
||||
'assign2' => $this->getDataGenerator()->create_module('assign', ['course' => $course->id]),
|
||||
'page1' => $this->getDataGenerator()->create_module('page', ['course' => $course->id]),
|
||||
'page2' => $this->getDataGenerator()->create_module('page', ['course' => $course->id]),
|
||||
];
|
||||
$availabilityjson = json_encode(\core_availability\tree::get_root_json(
|
||||
[
|
||||
\availability_date\condition::get_json(
|
||||
\availability_date\condition::DIRECTION_FROM,
|
||||
time() + 3600,
|
||||
),
|
||||
],
|
||||
'&',
|
||||
false,
|
||||
));
|
||||
$mods['page3'] = $this->getDataGenerator()->create_module('page', [
|
||||
'course' => $course->id,
|
||||
'visible' => true,
|
||||
'availability' => $availabilityjson,
|
||||
]);
|
||||
|
||||
$user = $this->getDataGenerator()->create_user();
|
||||
$this->getDataGenerator()->enrol_user($user->id, $course->id, 'editingteacher');
|
||||
$this->getDataGenerator()->enrol_user($user->id, $course->id, $role);
|
||||
$this->setUser($user);
|
||||
|
||||
$modinfo = get_fast_modinfo($course);
|
||||
|
||||
$cms = [
|
||||
'assign1' => $modinfo->get_cm($mods['assign1']->cmid),
|
||||
'assign2' => $modinfo->get_cm($mods['assign2']->cmid),
|
||||
'page1' => $modinfo->get_cm($mods['page1']->cmid),
|
||||
'page2' => $modinfo->get_cm($mods['page2']->cmid),
|
||||
'page3' => $modinfo->get_cm($mods['page3']->cmid),
|
||||
];
|
||||
|
||||
$renderer = \core\di::get(\core\output\renderer_helper::class)->get_core_renderer();
|
||||
|
||||
$overviewtable = new overviewtable($course, 'assign');
|
||||
$overviewtable = new overviewtable($course, 'page');
|
||||
|
||||
$data = $overviewtable->export_for_external();
|
||||
|
||||
$templatedata = $overviewtable->export_for_template($renderer);
|
||||
|
||||
$this->assertEquals($course, $data->course);
|
||||
$this->assertEquals(true, $data->hasintegration);
|
||||
$this->assertEquals(false, $data->hasintegration);
|
||||
|
||||
foreach ($templatedata->headers as $header) {
|
||||
$this->assertObjectHasProperty('name', $header);
|
||||
@@ -74,9 +98,9 @@ final class overviewtable_test extends \advanced_testcase {
|
||||
|
||||
$this->assertCount(4, get_object_vars($data));
|
||||
|
||||
$this->assertCount(2, $data->activities);
|
||||
$this->assertCount($expectedactivities, $data->activities);
|
||||
|
||||
$this->assertEquals($cms['assign1'], $data->activities[0]->cm);
|
||||
$this->assertEquals($cms['page1'], $data->activities[0]->cm);
|
||||
$this->assertEquals(false, $data->activities[0]->haserror);
|
||||
$this->assertCount(count($data->headers), $data->activities[0]->items);
|
||||
|
||||
@@ -88,4 +112,442 @@ final class overviewtable_test extends \advanced_testcase {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Data provider for test_export_for_external.
|
||||
*
|
||||
* @return \Generator The data provider array.
|
||||
*/
|
||||
public static function provider_export_for_external(): \Generator {
|
||||
yield 'Editing teacher' => [
|
||||
'role' => 'editingteacher',
|
||||
'expectedactivities' => 3,
|
||||
];
|
||||
yield 'Non-editing teacher' => [
|
||||
'role' => 'teacher',
|
||||
'expectedactivities' => 3,
|
||||
];
|
||||
yield 'Student' => [
|
||||
'role' => 'student',
|
||||
'expectedactivities' => 2,
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Test is_cm_displayable method for various visibility and stealth combinations.
|
||||
*
|
||||
* @param string $role The role of the user.
|
||||
* @param bool $visible Whether the activity is visible.
|
||||
* @param bool $stealth Whether the activity is displayed in the course page or not.
|
||||
* @param bool $expected The expected result.
|
||||
*/
|
||||
#[\PHPUnit\Framework\Attributes\DataProvider('provider_is_cm_displayable_visibility')]
|
||||
public function test_is_cm_displayable_visibility(
|
||||
string $role,
|
||||
bool $visible,
|
||||
bool $stealth,
|
||||
bool $expected
|
||||
): void {
|
||||
$this->resetAfterTest();
|
||||
set_config('allowstealth', true);
|
||||
|
||||
$course = $this->getDataGenerator()->create_course();
|
||||
$user = $this->getDataGenerator()->create_user();
|
||||
$this->getDataGenerator()->enrol_user($user->id, $course->id, $role);
|
||||
$this->setUser($user);
|
||||
|
||||
$mod = $this->getDataGenerator()->create_module('page', [
|
||||
'course' => $course->id,
|
||||
'visible' => $visible,
|
||||
'visibleoncoursepage' => !$stealth,
|
||||
]);
|
||||
$modinfo = get_fast_modinfo($course);
|
||||
$cm = $modinfo->get_cm($mod->cmid);
|
||||
|
||||
$this->assertEquals($visible, $cm->visible);
|
||||
$this->assertEquals($stealth, !$cm->visibleoncoursepage);
|
||||
|
||||
$this->assertEquals($expected, overviewtable::is_cm_displayable($cm));
|
||||
}
|
||||
|
||||
/**
|
||||
* Data provider for test_is_cm_displayable_visibility.
|
||||
*
|
||||
* @return \Generator The data provider array.
|
||||
*/
|
||||
public static function provider_is_cm_displayable_visibility(): \Generator {
|
||||
yield 'Editing teacher - Visible' => [
|
||||
'role' => 'editingteacher',
|
||||
'visible' => true,
|
||||
'stealth' => false,
|
||||
'expected' => true,
|
||||
];
|
||||
yield 'Editing teacher - Hidden' => [
|
||||
'role' => 'editingteacher',
|
||||
'visible' => false,
|
||||
'stealth' => false,
|
||||
'expected' => true,
|
||||
];
|
||||
yield 'Editing teacher - Stealth' => [
|
||||
'role' => 'editingteacher',
|
||||
'visible' => true,
|
||||
'stealth' => true,
|
||||
'expected' => true,
|
||||
];
|
||||
yield 'Teacher - Visible' => [
|
||||
'role' => 'teacher',
|
||||
'visible' => true,
|
||||
'stealth' => false,
|
||||
'expected' => true,
|
||||
];
|
||||
yield 'Teacher - Hidden' => [
|
||||
'role' => 'teacher',
|
||||
'visible' => false,
|
||||
'stealth' => false,
|
||||
'expected' => true,
|
||||
];
|
||||
yield 'Teacher - Stealth' => [
|
||||
'role' => 'teacher',
|
||||
'visible' => true,
|
||||
'stealth' => true,
|
||||
'expected' => true,
|
||||
];
|
||||
yield 'Student - Visible' => [
|
||||
'role' => 'student',
|
||||
'visible' => true,
|
||||
'stealth' => false,
|
||||
'expected' => true,
|
||||
];
|
||||
yield 'Student - Hidden' => [
|
||||
'role' => 'student',
|
||||
'visible' => false,
|
||||
'stealth' => false,
|
||||
'expected' => false,
|
||||
];
|
||||
yield 'Student - Stealth' => [
|
||||
'role' => 'student',
|
||||
'visible' => true,
|
||||
'stealth' => true,
|
||||
'expected' => true,
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Test is_cm_displayable method for modules without view page (like folder or text&media).
|
||||
*/
|
||||
public function test_is_cm_displayable_without_view_page(): void {
|
||||
$this->resetAfterTest();
|
||||
|
||||
$course = $this->getDataGenerator()->create_course();
|
||||
$user = $this->getDataGenerator()->create_user();
|
||||
$this->getDataGenerator()->enrol_user($user->id, $course->id, 'editingteacher');
|
||||
$this->setUser($user);
|
||||
|
||||
$modfolder = $this->getDataGenerator()->create_module('folder', [
|
||||
'course' => $course->id,
|
||||
'visible' => 1,
|
||||
]);
|
||||
$modtext = $this->getDataGenerator()->create_module('label', [
|
||||
'course' => $course->id,
|
||||
'visible' => 1,
|
||||
]);
|
||||
$modinfo = get_fast_modinfo($course);
|
||||
$cmfolder = $modinfo->get_cm($modfolder->cmid);
|
||||
$cmtext = $modinfo->get_cm($modtext->cmid);
|
||||
|
||||
$this->assertTrue(overviewtable::is_cm_displayable($cmfolder));
|
||||
$this->assertFalse(overviewtable::is_cm_displayable($cmtext));
|
||||
}
|
||||
|
||||
/**
|
||||
* Test is_cm_displayable method for various availability combinations.
|
||||
*
|
||||
* @param string $role The role of the user.
|
||||
* @param bool $visible Whether the activity is visible.
|
||||
* @param bool $isavailable Whether the activity is available.
|
||||
* @param bool $availabilityvisible Whether the availability info is shown.
|
||||
* @param bool $expected The expected result.
|
||||
*/
|
||||
#[\PHPUnit\Framework\Attributes\DataProvider('provider_is_cm_displayable_availability')]
|
||||
public function test_is_cm_displayable_availability(
|
||||
string $role,
|
||||
bool $visible,
|
||||
bool $isavailable,
|
||||
bool $availabilityvisible,
|
||||
bool $expected
|
||||
): void {
|
||||
$this->resetAfterTest();
|
||||
|
||||
$course = $this->getDataGenerator()->create_course();
|
||||
$user = $this->getDataGenerator()->create_user();
|
||||
$this->getDataGenerator()->enrol_user($user->id, $course->id, $role);
|
||||
$this->setUser($user);
|
||||
|
||||
// Set up the availability settings.
|
||||
$operation = \availability_date\condition::DIRECTION_FROM;
|
||||
$time = $isavailable ? time() - 3600 : time() + 3600;
|
||||
$availabilityjson = json_encode(\core_availability\tree::get_root_json(
|
||||
[
|
||||
\availability_date\condition::get_json($operation, $time),
|
||||
],
|
||||
'&',
|
||||
$availabilityvisible,
|
||||
));
|
||||
|
||||
$mod = $this->getDataGenerator()->create_module('page', [
|
||||
'course' => $course->id,
|
||||
'visible' => $visible,
|
||||
'availability' => $availabilityjson,
|
||||
]);
|
||||
$modinfo = get_fast_modinfo($course);
|
||||
$cm = $modinfo->get_cm($mod->cmid);
|
||||
|
||||
$this->assertEquals($visible, $cm->visible);
|
||||
$this->assertEquals($isavailable, $cm->available);
|
||||
if ($isavailable || !$visible) {
|
||||
$this->assertEmpty($cm->availableinfo);
|
||||
} else {
|
||||
$this->assertEquals($availabilityvisible, !empty($cm->availableinfo));
|
||||
}
|
||||
|
||||
$this->assertEquals($expected, overviewtable::is_cm_displayable($cm));
|
||||
}
|
||||
|
||||
/**
|
||||
* Data provider for test_is_cm_displayable_availability.
|
||||
*
|
||||
* @return \Generator The data provider array.
|
||||
*/
|
||||
public static function provider_is_cm_displayable_availability(): \Generator {
|
||||
yield 'Teacher - Visible - Available visible' => [
|
||||
'role' => 'teacher',
|
||||
'visible' => true,
|
||||
'isavailable' => true,
|
||||
'availabilityvisible' => true,
|
||||
'expected' => true,
|
||||
];
|
||||
yield 'Teacher - Visible - Unavailable visible' => [
|
||||
'role' => 'teacher',
|
||||
'visible' => true,
|
||||
'isavailable' => false,
|
||||
'availabilityvisible' => true,
|
||||
'expected' => true,
|
||||
];
|
||||
yield 'Teacher - Visible - Unavailable hidden' => [
|
||||
'role' => 'teacher',
|
||||
'visible' => true,
|
||||
'isavailable' => false,
|
||||
'availabilityvisible' => false,
|
||||
'expected' => true,
|
||||
];
|
||||
yield 'Teacher - Hidden - Available visible' => [
|
||||
'role' => 'teacher',
|
||||
'visible' => false,
|
||||
'isavailable' => true,
|
||||
'availabilityvisible' => true,
|
||||
'expected' => true,
|
||||
];
|
||||
yield 'Teacher - Hidden - Unavailable visible' => [
|
||||
'role' => 'teacher',
|
||||
'visible' => false,
|
||||
'isavailable' => false,
|
||||
'availabilityvisible' => true,
|
||||
'expected' => true,
|
||||
];
|
||||
yield 'Teacher - Hidden - Unavailable hidden' => [
|
||||
'role' => 'teacher',
|
||||
'visible' => false,
|
||||
'isavailable' => false,
|
||||
'availabilityvisible' => false,
|
||||
'expected' => true,
|
||||
];
|
||||
yield 'Student - Visible - Available visible' => [
|
||||
'role' => 'student',
|
||||
'visible' => true,
|
||||
'isavailable' => true,
|
||||
'availabilityvisible' => true,
|
||||
'expected' => true,
|
||||
];
|
||||
yield 'Student - Visible - Unavailable visible' => [
|
||||
'role' => 'student',
|
||||
'visible' => true,
|
||||
'isavailable' => false,
|
||||
'availabilityvisible' => true,
|
||||
'expected' => true,
|
||||
];
|
||||
yield 'Student - Visible - Unavailable hidden' => [
|
||||
'role' => 'student',
|
||||
'visible' => true,
|
||||
'isavailable' => false,
|
||||
'availabilityvisible' => false,
|
||||
'expected' => false,
|
||||
];
|
||||
yield 'Student - Hidden - Available visible' => [
|
||||
'role' => 'student',
|
||||
'visible' => false,
|
||||
'isavailable' => true,
|
||||
'availabilityvisible' => true,
|
||||
'expected' => false,
|
||||
];
|
||||
yield 'Student - Hidden - Unavailable visible' => [
|
||||
'role' => 'student',
|
||||
'visible' => false,
|
||||
'isavailable' => false,
|
||||
'availabilityvisible' => true,
|
||||
'expected' => false,
|
||||
];
|
||||
yield 'Student - Hidden - Unavailable hidden' => [
|
||||
'role' => 'student',
|
||||
'visible' => false,
|
||||
'isavailable' => false,
|
||||
'availabilityvisible' => false,
|
||||
'expected' => false,
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Test is_cm_available method.
|
||||
*
|
||||
* @param string $role The role of the user.
|
||||
* @param bool $visible Whether the activity is visible.
|
||||
* @param bool $isavailable Whether the activity is available.
|
||||
* @param bool $availabilityvisible Whether the availability info is shown.
|
||||
* @param bool $expected The expected result.
|
||||
*/
|
||||
#[\PHPUnit\Framework\Attributes\DataProvider('provider_is_cm_available')]
|
||||
public function test_is_cm_available(
|
||||
string $role,
|
||||
bool $visible,
|
||||
bool $isavailable,
|
||||
bool $availabilityvisible,
|
||||
bool $expected
|
||||
): void {
|
||||
$this->resetAfterTest();
|
||||
|
||||
$course = $this->getDataGenerator()->create_course();
|
||||
$user = $this->getDataGenerator()->create_user();
|
||||
$this->getDataGenerator()->enrol_user($user->id, $course->id, $role);
|
||||
$this->setUser($user);
|
||||
|
||||
// Set up the availability settings.
|
||||
$operation = \availability_date\condition::DIRECTION_FROM;
|
||||
$time = $isavailable ? time() - 3600 : time() + 3600;
|
||||
$availabilityjson = json_encode(\core_availability\tree::get_root_json(
|
||||
[
|
||||
\availability_date\condition::get_json($operation, $time),
|
||||
],
|
||||
'&',
|
||||
$availabilityvisible,
|
||||
));
|
||||
|
||||
$mod = $this->getDataGenerator()->create_module('page', [
|
||||
'course' => $course->id,
|
||||
'visible' => $visible,
|
||||
'availability' => $availabilityjson,
|
||||
]);
|
||||
$modinfo = get_fast_modinfo($course);
|
||||
$cm = $modinfo->get_cm($mod->cmid);
|
||||
|
||||
$this->assertEquals($visible, $cm->visible);
|
||||
$this->assertEquals($isavailable, $cm->available);
|
||||
if ($isavailable || !$visible) {
|
||||
$this->assertEmpty($cm->availableinfo);
|
||||
} else {
|
||||
$this->assertEquals($availabilityvisible, !empty($cm->availableinfo));
|
||||
}
|
||||
|
||||
$this->assertEquals($expected, overviewtable::is_cm_available($cm));
|
||||
}
|
||||
|
||||
/**
|
||||
* Data provider for test_is_cm_available.
|
||||
*
|
||||
* @return \Generator The data provider array.
|
||||
*/
|
||||
public static function provider_is_cm_available(): \Generator {
|
||||
yield 'Teacher - Visible - Available visible' => [
|
||||
'role' => 'teacher',
|
||||
'visible' => true,
|
||||
'isavailable' => true,
|
||||
'availabilityvisible' => true,
|
||||
'expected' => true,
|
||||
];
|
||||
yield 'Teacher - Visible - Unavailable visible' => [
|
||||
'role' => 'teacher',
|
||||
'visible' => true,
|
||||
'isavailable' => false,
|
||||
'availabilityvisible' => true,
|
||||
'expected' => true,
|
||||
];
|
||||
yield 'Teacher - Visible - Unavailable hidden' => [
|
||||
'role' => 'teacher',
|
||||
'visible' => true,
|
||||
'isavailable' => false,
|
||||
'availabilityvisible' => false,
|
||||
'expected' => true,
|
||||
];
|
||||
yield 'Teacher - Hidden - Available visible' => [
|
||||
'role' => 'teacher',
|
||||
'visible' => false,
|
||||
'isavailable' => true,
|
||||
'availabilityvisible' => true,
|
||||
'expected' => true,
|
||||
];
|
||||
yield 'Teacher - Hidden - Unavailable visible' => [
|
||||
'role' => 'teacher',
|
||||
'visible' => false,
|
||||
'isavailable' => false,
|
||||
'availabilityvisible' => true,
|
||||
'expected' => true,
|
||||
];
|
||||
yield 'Teacher - Hidden - Unavailable hidden' => [
|
||||
'role' => 'teacher',
|
||||
'visible' => false,
|
||||
'isavailable' => false,
|
||||
'availabilityvisible' => false,
|
||||
'expected' => true,
|
||||
];
|
||||
yield 'Student - Visible - Available visible' => [
|
||||
'role' => 'student',
|
||||
'visible' => true,
|
||||
'isavailable' => true,
|
||||
'availabilityvisible' => true,
|
||||
'expected' => true,
|
||||
];
|
||||
yield 'Student - Visible - Unavailable visible' => [
|
||||
'role' => 'student',
|
||||
'visible' => true,
|
||||
'isavailable' => false,
|
||||
'availabilityvisible' => true,
|
||||
'expected' => false,
|
||||
];
|
||||
yield 'Student - Visible - Unavailable hidden' => [
|
||||
'role' => 'student',
|
||||
'visible' => true,
|
||||
'isavailable' => false,
|
||||
'availabilityvisible' => false,
|
||||
'expected' => false,
|
||||
];
|
||||
yield 'Student - Hidden - Available visible' => [
|
||||
'role' => 'student',
|
||||
'visible' => false,
|
||||
'isavailable' => true,
|
||||
'availabilityvisible' => true,
|
||||
'expected' => true,
|
||||
];
|
||||
yield 'Student - Hidden - Unavailable visible' => [
|
||||
'role' => 'student',
|
||||
'visible' => false,
|
||||
'isavailable' => false,
|
||||
'availabilityvisible' => true,
|
||||
'expected' => false,
|
||||
];
|
||||
yield 'Student - Hidden - Unavailable hidden' => [
|
||||
'role' => 'student',
|
||||
'visible' => false,
|
||||
'isavailable' => false,
|
||||
'availabilityvisible' => false,
|
||||
'expected' => false,
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,8 +17,8 @@ Feature: Users can access the course activities overview page
|
||||
| teacher1 | C1 | editingteacher |
|
||||
| student1 | C1 | student |
|
||||
And the following "activities" exist:
|
||||
| activity | course | section | idnumber | name |
|
||||
| assign | C1 | 1 | 1 | Test assignment name |
|
||||
| activity | course | section | idnumber | name | duedate |
|
||||
| assign | C1 | 1 | 1 | Test assignment name | ##tomorrow noon## |
|
||||
|
||||
Scenario: Teacher can navigate to the course overview page
|
||||
Given I am on the "C1" "Course" page logged in as "teacher1"
|
||||
@@ -364,3 +364,29 @@ Feature: Users can access the course activities overview page
|
||||
# Student should not see the section name.
|
||||
But I am on the "Course 1" "course > activities > assign" page logged in as "student1"
|
||||
And I should not see "Section 1" in the "Test assignment name" "table_row"
|
||||
|
||||
@javascript
|
||||
Scenario: Unavailable activities are shown or hidden in the overview based on user capability
|
||||
# Add a date restriction to an activity, visible to students.
|
||||
Given I am on the "Test assignment name" "assign activity editing" page logged in as teacher1
|
||||
And I expand all fieldsets
|
||||
And I click on "Add restriction..." "button" in the "root" "core_availability > Availability Button Area"
|
||||
And I click on "Date" "button" in the "Add restriction..." "dialogue"
|
||||
And I set the field "Direction" in the "1" "availability_date > Date Restriction" to "until"
|
||||
And I press "Save and return to course"
|
||||
# Teacher can see the activity and the link in the overview.
|
||||
When I am on the "Course 1" "course > activities > assign" page logged in as "teacher1"
|
||||
Then I should see "Test assignment name" in the "assign_overview_collapsible" "region"
|
||||
And "Test assignment name" "link" should exist in the "assign_overview_collapsible" "region"
|
||||
And I should see "Name" in the "assign_overview_collapsible" "region"
|
||||
And I should see "Due date" in the "assign_overview_collapsible" "region"
|
||||
And I should see "Submissions" in the "assign_overview_collapsible" "region"
|
||||
And I should see "Actions" in the "assign_overview_collapsible" "region"
|
||||
# Student can see the activity but not the link in the overview.
|
||||
But I am on the "Course 1" "course > activities > assign" page logged in as "student1"
|
||||
And I should see "Test assignment name" in the "assign_overview_collapsible" "region"
|
||||
And "Test assignment name" "link" should not exist in the "assign_overview_collapsible" "region"
|
||||
And I should see "Name" in the "assign_overview_collapsible" "region"
|
||||
And I should see "Due date" in the "assign_overview_collapsible" "region"
|
||||
And I should not see "Submission status" in the "assign_overview_collapsible" "region"
|
||||
And I should not see "Grade" in the "assign_overview_collapsible" "region"
|
||||
|
||||
Reference in New Issue
Block a user