MDL-83896 mod_lesson: Add course overview integration
- Implement course overview integration - Redirect index.php to course overview
This commit is contained in:
@@ -121,7 +121,7 @@ final class overviewfactory_test extends \advanced_testcase {
|
||||
],
|
||||
'lesson' => [
|
||||
'resourcetype' => 'lesson',
|
||||
'expected' => resourceoverview::class,
|
||||
'expected' => \mod_lesson\courseformat\overview::class,
|
||||
],
|
||||
'lti' => [
|
||||
'resourcetype' => 'lti',
|
||||
|
||||
@@ -75,7 +75,7 @@ final class missingoverviewnotice_test extends \advanced_testcase {
|
||||
'h5pactivity' => ['modname' => 'h5pactivity', 'expectempty' => true],
|
||||
'imscp' => ['modname' => 'imscp', 'expectempty' => false],
|
||||
'label' => ['modname' => 'label', 'expectempty' => false],
|
||||
'lesson' => ['modname' => 'lesson', 'expectempty' => false],
|
||||
'lesson' => ['modname' => 'lesson', 'expectempty' => true],
|
||||
'lti' => ['modname' => 'lti', 'expectempty' => false],
|
||||
'page' => ['modname' => 'page', 'expectempty' => false],
|
||||
'qbank' => ['modname' => 'qbank', 'expectempty' => false],
|
||||
|
||||
@@ -0,0 +1,166 @@
|
||||
<?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/>.
|
||||
|
||||
namespace mod_lesson\courseformat;
|
||||
|
||||
use core\output\action_link;
|
||||
use core\output\local\properties\button;
|
||||
use core\output\local\properties\text_align;
|
||||
use core\url;
|
||||
use core_courseformat\output\local\overview\overviewdialog;
|
||||
use lesson;
|
||||
use core_calendar\output\humandate;
|
||||
use core_courseformat\local\overview\overviewitem;
|
||||
use cm_info;
|
||||
|
||||
/**
|
||||
* Class overview
|
||||
*
|
||||
* @package mod_lesson
|
||||
* @copyright 2025 Mikel Martín <[email protected]>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
class overview extends \core_courseformat\activityoverviewbase {
|
||||
/** @var array $deadlines user's deadline for all lessons in the course. */
|
||||
private array $deadlines;
|
||||
|
||||
/** @var lesson $lesson the lesson instance. */
|
||||
private lesson $lesson;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param cm_info $cm the course module instance.
|
||||
* @param \core\output\renderer_helper $rendererhelper the renderer helper.
|
||||
* @param \core_string_manager $stringmanager the string manager.
|
||||
*/
|
||||
public function __construct(
|
||||
cm_info $cm,
|
||||
/** @var \core\output\renderer_helper $rendererhelper the renderer helper */
|
||||
protected readonly \core\output\renderer_helper $rendererhelper,
|
||||
/** @var \core_string_manager $sm the string manager */
|
||||
protected readonly \core_string_manager $stringmanager,
|
||||
) {
|
||||
global $CFG;
|
||||
require_once($CFG->dirroot . '/mod/lesson/locallib.php');
|
||||
parent::__construct($cm);
|
||||
$this->lesson = new lesson($this->cm->get_instance_record());
|
||||
$this->deadlines = lesson_get_user_deadline($this->cm->get_course()->id);
|
||||
}
|
||||
|
||||
#[\Override]
|
||||
public function get_due_date_overview(): ?overviewitem {
|
||||
$duedate = null;
|
||||
if (isset($this->deadlines[$this->lesson->id])) {
|
||||
$duedate = $this->deadlines[$this->lesson->id]->userdeadline;
|
||||
}
|
||||
|
||||
return new overviewitem(
|
||||
name: $this->stringmanager->get_string('duedate', 'mod_lesson'),
|
||||
value: $duedate,
|
||||
content: $duedate ? humandate::create_from_timestamp($duedate) : '-',
|
||||
);
|
||||
}
|
||||
|
||||
#[\Override]
|
||||
public function get_actions_overview(): ?overviewitem {
|
||||
if (!has_capability('mod/lesson:manage', $this->context)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$content = new action_link(
|
||||
url: new url('/mod/lesson/report.php', ['id' => $this->cm->id, 'action' => 'reportoverview']),
|
||||
text: $this->stringmanager->get_string('view', 'mod_lesson'),
|
||||
attributes: ['class' => button::SECONDARY_OUTLINE->classes()],
|
||||
);
|
||||
|
||||
return new overviewitem(
|
||||
name: $this->stringmanager->get_string('actions'),
|
||||
value: '',
|
||||
content: $content,
|
||||
);
|
||||
}
|
||||
|
||||
#[\Override]
|
||||
public function get_extra_overview_items(): array {
|
||||
return [
|
||||
'attemptedstudents' => $this->get_extra_attemptedstudents_overview(),
|
||||
'totalattempts' => $this->get_extra_totalattempts_overview(),
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the extra overview for attempted students.
|
||||
*
|
||||
* @return overviewitem|null The overview item (or null if the user cannot manage lesson activity).
|
||||
*/
|
||||
protected function get_extra_attemptedstudents_overview(): ?overviewitem {
|
||||
if (!has_capability('mod/lesson:manage', $this->context)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$attemptedusers = $this->lesson->count_submitted_participants();
|
||||
$totalusers = $this->lesson->count_all_participants();
|
||||
|
||||
return new overviewitem(
|
||||
name: $this->stringmanager->get_string('studentswhoattempted', 'mod_lesson'),
|
||||
value: $attemptedusers,
|
||||
content: $this->stringmanager->get_string(
|
||||
'count_of_total',
|
||||
'core',
|
||||
['count' => $attemptedusers, 'total' => $totalusers]
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the extra overview for attempted students.
|
||||
*
|
||||
* @return overviewitem|null The overview item (or null if the user cannot manage lesson activity).
|
||||
*/
|
||||
protected function get_extra_totalattempts_overview(): ?overviewitem {
|
||||
if (!has_capability('mod/lesson:manage', $this->context)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$totalattempts = $this->lesson->count_all_submissions();
|
||||
|
||||
if ($this->lesson->retake) {
|
||||
$attemptedusers = $this->lesson->count_submitted_participants();
|
||||
|
||||
$overviewdialog = new overviewdialog(
|
||||
buttoncontent: $totalattempts,
|
||||
description: $this->stringmanager->get_string('retakesallowedinfo', 'mod_lesson'),
|
||||
definition: ['buttonclasses' => button::SECONDARY_OUTLINE->classes() . ' dropdown-toggle'],
|
||||
);
|
||||
|
||||
$averageattempts = $totalattempts ? round($totalattempts / $attemptedusers) : 0;
|
||||
$overviewdialog->add_item(
|
||||
$this->stringmanager->get_string('averageattempts', 'mod_lesson'),
|
||||
$averageattempts
|
||||
);
|
||||
}
|
||||
|
||||
// If the lesson does not allow retakes, do not show the dialog, only the total attepmts number.
|
||||
// And also, set the value to null, that will hide the whole column if every lesson does not allow retakes.
|
||||
return new overviewitem(
|
||||
name: $this->stringmanager->get_string('totalattepmts', 'mod_lesson'),
|
||||
value: !empty($overviewdialog) ? $totalattempts : null,
|
||||
content: $overviewdialog ?? $totalattempts,
|
||||
textalign: text_align::CENTER,
|
||||
);
|
||||
}
|
||||
}
|
||||
+2
-94
@@ -23,100 +23,8 @@
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
**/
|
||||
|
||||
/** Include required files */
|
||||
require_once("../../config.php");
|
||||
require_once($CFG->dirroot.'/mod/lesson/locallib.php');
|
||||
|
||||
$id = required_param('id', PARAM_INT); // course
|
||||
$courseid = required_param('id', PARAM_INT);
|
||||
|
||||
$PAGE->set_url('/mod/lesson/index.php', array('id'=>$id));
|
||||
|
||||
if (!$course = $DB->get_record("course", array("id" => $id))) {
|
||||
throw new \moodle_exception('invalidcourseid');
|
||||
}
|
||||
|
||||
require_login($course);
|
||||
$PAGE->set_pagelayout('incourse');
|
||||
|
||||
// Trigger instances list viewed event.
|
||||
$params = array(
|
||||
'context' => context_course::instance($course->id)
|
||||
);
|
||||
$event = \mod_lesson\event\course_module_instance_list_viewed::create($params);
|
||||
$event->add_record_snapshot('course', $course);
|
||||
$event->trigger();
|
||||
|
||||
/// Get all required strings
|
||||
|
||||
$strlessons = get_string("modulenameplural", "lesson");
|
||||
$strlesson = get_string("modulename", "lesson");
|
||||
|
||||
|
||||
/// Print the header
|
||||
$PAGE->navbar->add($strlessons);
|
||||
$PAGE->set_title("$course->shortname: $strlessons");
|
||||
$PAGE->set_heading($course->fullname);
|
||||
echo $OUTPUT->header();
|
||||
echo $OUTPUT->heading($strlessons, 2);
|
||||
|
||||
/// Get all the appropriate data
|
||||
|
||||
if (! $lessons = get_all_instances_in_course("lesson", $course)) {
|
||||
notice(get_string('thereareno', 'moodle', $strlessons), "../../course/view.php?id=$course->id");
|
||||
die;
|
||||
}
|
||||
|
||||
$usesections = course_format_uses_sections($course->format);
|
||||
|
||||
/// Print the list of instances (your module will probably extend this)
|
||||
|
||||
$timenow = time();
|
||||
$strname = get_string("name");
|
||||
$strgrade = get_string("gradenoun");
|
||||
$strdeadline = get_string("deadline", "lesson");
|
||||
$strnodeadline = get_string("nodeadline", "lesson");
|
||||
$table = new html_table();
|
||||
|
||||
if ($usesections) {
|
||||
$strsectionname = course_get_format($course)->get_generic_section_name();
|
||||
$table->head = array ($strsectionname, $strname, $strgrade, $strdeadline);
|
||||
$table->align = array ("center", "left", "center", "center");
|
||||
} else {
|
||||
$table->head = array ($strname, $strgrade, $strdeadline);
|
||||
$table->align = array ("left", "center", "center");
|
||||
}
|
||||
// Get all deadlines.
|
||||
$deadlines = lesson_get_user_deadline($course->id);
|
||||
foreach ($lessons as $lesson) {
|
||||
$cm = get_coursemodule_from_instance('lesson', $lesson->id);
|
||||
$context = context_module::instance($cm->id);
|
||||
|
||||
$class = $lesson->visible ? null : array('class' => 'dimmed'); // Hidden modules are dimmed.
|
||||
$link = html_writer::link(new moodle_url('view.php', array('id' => $cm->id)), format_string($lesson->name, true), $class);
|
||||
|
||||
$deadline = $deadlines[$lesson->id]->userdeadline;
|
||||
if ($deadline == 0) {
|
||||
$due = $strnodeadline;
|
||||
} else if ($deadline > $timenow) {
|
||||
$due = userdate($deadline);
|
||||
} else {
|
||||
$due = html_writer::tag('span', userdate($deadline), array('class' => 'text-danger'));
|
||||
}
|
||||
|
||||
if ($usesections) {
|
||||
if (has_capability('mod/lesson:manage', $context)) {
|
||||
$grade_value = $lesson->grade;
|
||||
} else {
|
||||
// it's a student, show their grade
|
||||
$grade_value = 0;
|
||||
if ($return = lesson_get_user_grades($lesson, $USER->id)) {
|
||||
$grade_value = $return[$USER->id]->rawgrade;
|
||||
}
|
||||
}
|
||||
$table->data[] = array (get_section_name($course, $lesson->section), $link, $grade_value, $due);
|
||||
} else {
|
||||
$table->data[] = array ($link, $lesson->grade, $due);
|
||||
}
|
||||
}
|
||||
echo html_writer::table($table);
|
||||
echo $OUTPUT->footer();
|
||||
\core_courseformat\activityoverviewbase::redirect_to_overview_page($courseid, 'lesson');
|
||||
|
||||
@@ -61,6 +61,7 @@ $string['addtruefalse'] = 'Create a True/false question page';
|
||||
$string['allotheranswers'] = 'All other answers';
|
||||
$string['allotheranswersjump'] = 'All other answers jump';
|
||||
$string['allotheranswersscore'] = 'All other answers score';
|
||||
$string['allowedattempts'] = 'Allowed attempts per student';
|
||||
$string['allowofflineattempts'] = 'Allow lesson to be attempted offline using the mobile app';
|
||||
$string['allowofflineattempts_help'] = 'If enabled, a mobile app user can download the lesson and attempt it offline.
|
||||
All the possible answers and correct responses will be downloaded as well.
|
||||
@@ -79,6 +80,7 @@ $string['attempts'] = 'Attempts';
|
||||
$string['attemptsdeleted'] = 'Deleted attempts';
|
||||
$string['attemptsremaining'] = 'You have {$a} attempt(s) remaining';
|
||||
$string['available'] = 'Available from';
|
||||
$string['averageattempts'] = 'Average attempts per student';
|
||||
$string['averagescore'] = 'Average score';
|
||||
$string['averagetime'] = 'Average time';
|
||||
$string['branch'] = 'Content';
|
||||
@@ -175,6 +177,7 @@ $string['displayscorewithessays'] = '<p>You earned {$a->score} out of {$a->tempm
|
||||
<p>Your {$a->essayquestions} essay question(s) will be graded and added into your final score at a later date.</p>
|
||||
<p>Your current grade without the essay question(s) is {$a->score} out of {$a->grade}.</p>';
|
||||
$string['displayscorewithoutessays'] = 'Your score is {$a->score} (out of {$a->grade}).';
|
||||
$string['duedate'] = 'Due date';
|
||||
$string['duplicatepagenamed'] = 'Duplicate page: {$a}';
|
||||
$string['edit'] = 'Edit';
|
||||
$string['editbranchtable'] = 'Editing a content page';
|
||||
@@ -522,6 +525,7 @@ $string['reports'] = 'Reports';
|
||||
$string['response'] = 'Response';
|
||||
$string['retakesallowed'] = 'Allow multiple attempts';
|
||||
$string['retakesallowed_help'] = 'Allow students to attempt the lesson more than once.';
|
||||
$string['retakesallowedinfo'] = 'This Lesson allows students to do multiple attempts.';
|
||||
$string['returnto'] = 'Return to {$a}';
|
||||
$string['returntocourse'] = 'Return to the course';
|
||||
$string['reverttodefaults'] = 'Revert to lesson defaults';
|
||||
@@ -560,6 +564,7 @@ $string['studentname'] = '{$a} Name';
|
||||
$string['studentoneminwarning'] = 'Warning: You have 1 minute or less to finish the lesson.';
|
||||
$string['studentoutoftimeforreview'] = 'Attention: You ran out of time for reviewing this lesson';
|
||||
$string['studentresponse'] = '{$a}\'s response';
|
||||
$string['studentswhoattempted'] = 'Students who attempted';
|
||||
$string['submit'] = 'Submit';
|
||||
$string['submitname'] = 'Submit name';
|
||||
$string['teacherjumpwarning'] = 'A {$a->cluster} jump or an {$a->unseen} jump is being used in this lesson. The next page jump will be used instead. Log in as a student to test these jumps.';
|
||||
@@ -577,6 +582,7 @@ $string['timeremaining'] = 'Time remaining';
|
||||
$string['timespenterror'] = 'Spend at least {$a} minutes in the lesson';
|
||||
$string['timespentminutes'] = 'Time spent (minutes)';
|
||||
$string['timetaken'] = 'Time taken';
|
||||
$string['totalattepmts'] = 'Total attempts';
|
||||
$string['totalpagesviewedheader'] = 'Number of pages viewed';
|
||||
$string['true'] = 'True';
|
||||
$string['truefalse'] = 'True/false';
|
||||
@@ -593,6 +599,7 @@ $string['usepassword'] = 'Password protected lesson';
|
||||
$string['usepassword_help'] = 'If enabled, a password is required in order to access the lesson.';
|
||||
$string['useroverrides'] = 'User overrides';
|
||||
$string['usersnone'] = 'No students have access to this lesson';
|
||||
$string['view'] = 'View';
|
||||
$string['viewessayanswers'] = 'View essay answers';
|
||||
$string['viewgrades'] = 'View grades';
|
||||
$string['viewreports'] = 'View {$a->attempts} completed {$a->student} attempts';
|
||||
|
||||
@@ -0,0 +1,103 @@
|
||||
@mod @mod_lesson
|
||||
Feature: Testing overview_report in mod_lesson
|
||||
In order to list all lessons in a course
|
||||
As a user
|
||||
I need to be able to see the lesson overview
|
||||
|
||||
Background:
|
||||
Given the following "users" exist:
|
||||
| username | firstname | lastname |
|
||||
| student1 | Username | 1 |
|
||||
| student2 | Username | 2 |
|
||||
| student3 | Username | 3 |
|
||||
| teacher1 | Teacher | T |
|
||||
And the following "courses" exist:
|
||||
| fullname | shortname | groupmode |
|
||||
| Course 1 | C1 | 1 |
|
||||
And the following "course enrolments" exist:
|
||||
| user | course | role |
|
||||
| student1 | C1 | student |
|
||||
| student2 | C1 | student |
|
||||
| student3 | C1 | student |
|
||||
| teacher1 | C1 | editingteacher |
|
||||
And the following "activities" exist:
|
||||
| activity | name | course | idnumber | retake | deadline |
|
||||
| lesson | Lesson 1 | C1 | lesson1 | 1 | ##tomorrow## |
|
||||
| lesson | Lesson 2 | C1 | lesson2 | 0 | 0 |
|
||||
And the following "mod_lesson > pages" exist:
|
||||
| lesson | qtype | title | content |
|
||||
| lesson1 | truefalse | Question 1 | The number 10 is greater than 5 |
|
||||
And the following "mod_lesson > answers" exist:
|
||||
| page | answer | jumpto | score |
|
||||
| Question 1 | True | End of lesson | 1 |
|
||||
| Question 1 | False | End of lesson | 0 |
|
||||
And the following "mod_lesson > submissions" exist:
|
||||
| lesson | user | grade |
|
||||
| Lesson 1 | student1 | 50 |
|
||||
| Lesson 1 | student1 | 60 |
|
||||
| Lesson 1 | student1 | 100 |
|
||||
| Lesson 1 | student2 | 90 |
|
||||
|
||||
@javascript
|
||||
Scenario: Teacher can see the lesson relevant information in the lesson overview
|
||||
When I am on the "Course 1" "course > activities > lesson" page logged in as "teacher1"
|
||||
Then the following should exist in the "Table listing all Lesson activities" table:
|
||||
| Name | Students who attempted | Total attempts | Due date |
|
||||
| Lesson 1 | 2 of 3 | 4 | Tomorrow |
|
||||
| Lesson 2 | 0 of 3 | 0 | - |
|
||||
And I click on "4" "button" in the "Lesson 1" "table_row"
|
||||
And I should see "This Lesson allows students to do multiple attempts."
|
||||
And I should see "Average attempts per student: 2"
|
||||
And I press the escape key
|
||||
And "0" "button" should not exist in the "Lesson 2" "table_row"
|
||||
And I click on "View" "link" in the "Lesson 1" "table_row"
|
||||
And I should see "Reports" in the "page-header" "region"
|
||||
|
||||
Scenario: Teacher can see the lesson overview with all lessons with retakes disabled
|
||||
Given the following "courses" exist:
|
||||
| fullname | shortname |
|
||||
| Course 2 | C2 |
|
||||
And the following "course enrolments" exist:
|
||||
| user | course | role |
|
||||
| student1 | C2 | student |
|
||||
| teacher1 | C2 | editingteacher |
|
||||
And the following "activities" exist:
|
||||
| activity | name | course | idnumber | retake |
|
||||
| lesson | Lesson 1 | C2 | lesson1 | 0 |
|
||||
| lesson | Lesson 2 | C2 | lesson2 | 0 |
|
||||
When I am on the "Course 2" "course > activities > lesson" page logged in as "teacher1"
|
||||
Then I should not see "Total attempts" in the "lesson_overview_collapsible" "region"
|
||||
And the following should exist in the "Table listing all Lesson activities" table:
|
||||
| Name | Students who attempted | Due date |
|
||||
| Lesson 1 | 0 of 1 | - |
|
||||
| Lesson 2 | 0 of 1 | - |
|
||||
|
||||
Scenario: Students can see the lesson relevant information in the lesson overview
|
||||
When I am on the "Course 1" "course > activities > lesson" page logged in as "student1"
|
||||
Then I should not see "Actions" in the "lesson_overview_collapsible" "region"
|
||||
And I should not see "Students who attempted" in the "lesson_overview_collapsible" "region"
|
||||
And I should not see "Total attempts" in the "lesson_overview_collapsible" "region"
|
||||
And the following should exist in the "Table listing all Lesson activities" table:
|
||||
| Name | Due date |
|
||||
| Lesson 1 | Tomorrow |
|
||||
| Lesson 2 | - |
|
||||
|
||||
Scenario: The lesson index redirect to the activities overview
|
||||
When I log in as "admin"
|
||||
And I am on "Course 1" course homepage with editing mode on
|
||||
And I add the "Activities" block
|
||||
And I click on "Lessons" "link" in the "Activities" "block"
|
||||
Then I should see "An overview of all activities in the course, with dates and other information."
|
||||
And I should see "Name" in the "lesson_overview_collapsible" "region"
|
||||
And I should see "Students who attempted" in the "lesson_overview_collapsible" "region"
|
||||
And I should see "Total attempts" in the "lesson_overview_collapsible" "region"
|
||||
And I should see "Actions" in the "lesson_overview_collapsible" "region"
|
||||
|
||||
Scenario: The lesson overview report should generate log events
|
||||
Given I am on the "Course 1" "course > activities > lesson" page logged in as "teacher1"
|
||||
When I am on the "Course 1" "course" page logged in as "teacher1"
|
||||
And I navigate to "Reports" in current page administration
|
||||
And I click on "Logs" "link"
|
||||
And I click on "Get these logs" "button"
|
||||
Then I should see "Course activities overview page viewed"
|
||||
And I should see "viewed the instance list for the module 'lesson'"
|
||||
@@ -0,0 +1,366 @@
|
||||
<?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/>.
|
||||
|
||||
namespace mod_lesson\courseformat;
|
||||
|
||||
use core_courseformat\local\overview\overviewfactory;
|
||||
use lesson;
|
||||
|
||||
/**
|
||||
* Tests for Lesson overview.
|
||||
*
|
||||
* @package mod_lesson
|
||||
* @category test
|
||||
* @copyright 2025 Mikel Martín <[email protected]>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
final class overview_test extends \advanced_testcase {
|
||||
/**
|
||||
* Helper function to create lesson pages with multichoice questions.
|
||||
*
|
||||
* @param lesson $lesson The lesson object.
|
||||
* @param int $count The number of multichoice questions to create.
|
||||
*/
|
||||
private function create_lesson_pages(lesson $lesson, int $count): void {
|
||||
/** @var \mod_lesson_generator $lessongenerator */
|
||||
$lessongenerator = $this->getDataGenerator()->get_plugin_generator('mod_lesson');
|
||||
|
||||
for ($i = 0; $i < $count; $i++) {
|
||||
$lessongenerator->create_page([
|
||||
'title' => 'Multichoice question' . ($i + 1),
|
||||
'content' => 'Question content',
|
||||
'qtype' => 'multichoice',
|
||||
'lessonid' => $lesson->id,
|
||||
]);
|
||||
$lessongenerator->create_answer(['page' => 'Multichoice question' . ($i + 1), 'answer' => 'A', 'score' => 1]);
|
||||
$lessongenerator->create_answer(['page' => 'Multichoice question' . ($i + 1), 'answer' => 'B']);
|
||||
}
|
||||
$lessongenerator->finish_generate_answer();
|
||||
}
|
||||
|
||||
/**
|
||||
* Test get_due_date_overview.
|
||||
*
|
||||
* @covers ::get_due_date_overview
|
||||
* @dataProvider provider_test_get_due_date_overview
|
||||
*
|
||||
* @param int|null $timeincrement the time increment in seconds to add to the current time for the deadline.
|
||||
* @return void
|
||||
*/
|
||||
public function test_get_due_date_overview(?int $timeincrement): void {
|
||||
$this->resetAfterTest();
|
||||
$this->setAdminUser();
|
||||
|
||||
$course = $this->getDataGenerator()->create_course();
|
||||
$student = $this->getDataGenerator()->create_and_enrol($course, 'student');
|
||||
|
||||
$deadline = $timeincrement ? $this->mock_clock_with_frozen()->time() + $timeincrement : 0;
|
||||
$lesson = $this->getDataGenerator()->create_module(
|
||||
'lesson',
|
||||
[
|
||||
'course' => $course->id,
|
||||
'deadline' => $deadline,
|
||||
],
|
||||
);
|
||||
|
||||
$this->setUser($student);
|
||||
|
||||
$cm = get_fast_modinfo($course)->get_cm($lesson->cmid);
|
||||
$item = overviewfactory::create($cm)->get_due_date_overview();
|
||||
|
||||
$this->assertEquals(get_string('duedate', 'lesson'), $item->get_name());
|
||||
$this->assertEquals($deadline, $item->get_value());
|
||||
}
|
||||
|
||||
/**
|
||||
* Provider for test_get_due_date_overview.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function provider_test_get_due_date_overview(): array {
|
||||
return [
|
||||
'no_due' => [
|
||||
'timeincrement' => null,
|
||||
],
|
||||
'past_due' => [
|
||||
'timeincrement' => -1 * (4 * DAYSECS),
|
||||
],
|
||||
'future_due' => [
|
||||
'timeincrement' => (4 * DAYSECS),
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Test get_actions_overview.
|
||||
*
|
||||
* @covers ::get_actions_overview
|
||||
* @dataProvider provider_test_get_actions_overview
|
||||
*
|
||||
* @param string $role
|
||||
* @param array|null $expected
|
||||
* @return void
|
||||
*/
|
||||
public function test_get_actions_overview(
|
||||
string $role,
|
||||
?array $expected
|
||||
): void {
|
||||
$this->resetAfterTest();
|
||||
$this->setAdminUser();
|
||||
|
||||
$course = $this->getDataGenerator()->create_course();
|
||||
$currentuser = $this->getDataGenerator()->create_and_enrol($course, $role);
|
||||
$lesson = $this->getDataGenerator()->create_module( 'lesson', ['course' => $course->id]);
|
||||
|
||||
$this->setUser($currentuser);
|
||||
|
||||
$cm = get_fast_modinfo($course)->get_cm($lesson->cmid);
|
||||
$item = overviewfactory::create($cm)->get_actions_overview();
|
||||
|
||||
if ($expected === null) {
|
||||
$this->assertNull($item);
|
||||
return;
|
||||
}
|
||||
|
||||
$this->assertEquals(
|
||||
$expected,
|
||||
['name' => $item->get_name(), 'value' => $item->get_value()]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Data provider for test_get_actions_overview.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function provider_test_get_actions_overview(): array {
|
||||
return [
|
||||
'Student' => [
|
||||
'role' => 'student',
|
||||
'expected' => null,
|
||||
],
|
||||
'Teacher' => [
|
||||
'role' => 'editingteacher',
|
||||
'expected' => [
|
||||
'name' => get_string('actions'),
|
||||
'value' => '',
|
||||
],
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Test get_extra_totalattempts_overview.
|
||||
*
|
||||
* @covers ::get_extra_totalattempts_overview
|
||||
* @dataProvider provider_test_get_extra_totalattempts_overview
|
||||
*
|
||||
* @param string $role
|
||||
* @param bool $hasentries
|
||||
* @param bool $hasretakes
|
||||
* @param array|null $expected
|
||||
* @return void
|
||||
*/
|
||||
public function test_get_extra_totalattempts_overview(
|
||||
string $role,
|
||||
bool $hasentries,
|
||||
bool $hasretakes,
|
||||
?array $expected
|
||||
): void {
|
||||
$this->resetAfterTest();
|
||||
$this->setAdminUser();
|
||||
|
||||
$course = $this->getDataGenerator()->create_course();
|
||||
$student1 = $this->getDataGenerator()->create_and_enrol($course, 'student');
|
||||
$currentuser = $this->getDataGenerator()->create_and_enrol($course, $role);
|
||||
|
||||
$lessonmodule = $this->getDataGenerator()->create_module(
|
||||
'lesson',
|
||||
['course' => $course, 'retake' => $hasretakes]
|
||||
);
|
||||
$cm = get_fast_modinfo($course)->get_cm($lessonmodule->cmid);
|
||||
$lesson = new lesson($lessonmodule);
|
||||
/** @var \mod_lesson_generator $lessongenerator */
|
||||
$lessongenerator = $this->getDataGenerator()->get_plugin_generator('mod_lesson');
|
||||
$this->create_lesson_pages($lesson, 2);
|
||||
|
||||
if ($hasentries) {
|
||||
$lessongenerator->create_submission([
|
||||
'lessonid' => $lesson->id,
|
||||
'userid' => $student1->id,
|
||||
'grade' => 100,
|
||||
]);
|
||||
$lessongenerator->create_submission([
|
||||
'lessonid' => $lesson->id,
|
||||
'userid' => $currentuser->id,
|
||||
'grade' => 100,
|
||||
]);
|
||||
}
|
||||
|
||||
$this->setUser($currentuser);
|
||||
$overview = overviewfactory::create($cm);
|
||||
$reflection = new \ReflectionClass($overview);
|
||||
$method = $reflection->getMethod('get_extra_totalattempts_overview');
|
||||
$method->setAccessible(true);
|
||||
$item = $method->invoke($overview);
|
||||
|
||||
if ($expected === null) {
|
||||
$this->assertNull($item);
|
||||
return;
|
||||
}
|
||||
|
||||
$this->assertEquals(
|
||||
$expected,
|
||||
['name' => $item->get_name(), 'value' => $item->get_value()]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Data provider for test_get_extra_totalattempts_overview.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function provider_test_get_extra_totalattempts_overview(): array {
|
||||
return [
|
||||
'Teacher (with attempts)' => [
|
||||
'role' => 'editingteacher',
|
||||
'hasentries' => true,
|
||||
'hasretakes' => true,
|
||||
'expected' => [
|
||||
'name' => get_string('totalattepmts', 'mod_lesson'),
|
||||
'value' => 2,
|
||||
],
|
||||
],
|
||||
'Teacher (with attempts without retakes)' => [
|
||||
'role' => 'editingteacher',
|
||||
'hasentries' => true,
|
||||
'hasretakes' => false,
|
||||
'expected' => [
|
||||
'name' => get_string('totalattepmts', 'mod_lesson'),
|
||||
'value' => null,
|
||||
],
|
||||
],
|
||||
'Teacher (without attempts)' => [
|
||||
'role' => 'editingteacher',
|
||||
'hasentries' => false,
|
||||
'hasretakes' => true,
|
||||
'expected' => [
|
||||
'name' => get_string('totalattepmts', 'mod_lesson'),
|
||||
'value' => 0,
|
||||
],
|
||||
],
|
||||
'Student' => [
|
||||
'role' => 'student',
|
||||
'hasentries' => true,
|
||||
'hasretakes' => true,
|
||||
'expected' => null,
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Test get_extra_attemptedstudents_overview.
|
||||
*
|
||||
* @covers ::get_extra_attemptedstudents_overview
|
||||
* @dataProvider provider_test_get_extra_attemptedstudents_overview
|
||||
*
|
||||
* @param string $role
|
||||
* @param bool $hasentries
|
||||
* @param array|null $expected
|
||||
* @return void
|
||||
*/
|
||||
public function test_get_extra_attemptedstudents_overview(
|
||||
string $role,
|
||||
bool $hasentries,
|
||||
?array $expected
|
||||
): void {
|
||||
$this->resetAfterTest();
|
||||
$this->setAdminUser();
|
||||
|
||||
$course = $this->getDataGenerator()->create_course();
|
||||
$student1 = $this->getDataGenerator()->create_and_enrol($course, 'student');
|
||||
$student2 = $this->getDataGenerator()->create_and_enrol($course, 'student');
|
||||
$currentuser = $this->getDataGenerator()->create_and_enrol($course, $role);
|
||||
|
||||
$lessonmodule = $this->getDataGenerator()->create_module('lesson', ['course' => $course]);
|
||||
$cm = get_fast_modinfo($course)->get_cm($lessonmodule->cmid);
|
||||
$lesson = new lesson($lessonmodule);
|
||||
/** @var \mod_lesson_generator $lessongenerator */
|
||||
$lessongenerator = $this->getDataGenerator()->get_plugin_generator('mod_lesson');
|
||||
$this->create_lesson_pages($lesson, 2);
|
||||
|
||||
if ($hasentries) {
|
||||
$lessongenerator->create_submission([
|
||||
'lessonid' => $lesson->id,
|
||||
'userid' => $student1->id,
|
||||
'grade' => 100,
|
||||
]);
|
||||
$lessongenerator->create_submission([
|
||||
'lessonid' => $lesson->id,
|
||||
'userid' => $currentuser->id,
|
||||
'grade' => 100,
|
||||
]);
|
||||
}
|
||||
|
||||
$this->setUser($currentuser);
|
||||
$overview = overviewfactory::create($cm);
|
||||
$reflection = new \ReflectionClass($overview);
|
||||
$method = $reflection->getMethod('get_extra_attemptedstudents_overview');
|
||||
$method->setAccessible(true);
|
||||
$item = $method->invoke($overview);
|
||||
|
||||
if ($expected === null) {
|
||||
$this->assertNull($item);
|
||||
return;
|
||||
}
|
||||
|
||||
$this->assertEquals(
|
||||
$expected,
|
||||
['name' => $item->get_name(), 'value' => (int)$item->get_value()]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Data provider for test_get_extra_attemptedstudents_overview.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function provider_test_get_extra_attemptedstudents_overview(): array {
|
||||
return [
|
||||
'Teacher (with attempts)' => [
|
||||
'role' => 'editingteacher',
|
||||
'hasentries' => true,
|
||||
'expected' => [
|
||||
'name' => get_string('studentswhoattempted', 'mod_lesson'),
|
||||
'value' => 2,
|
||||
],
|
||||
],
|
||||
'Teacher (without attempts)' => [
|
||||
'role' => 'editingteacher',
|
||||
'hasentries' => false,
|
||||
'expected' => [
|
||||
'name' => get_string('studentswhoattempted', 'mod_lesson'),
|
||||
'value' => 0,
|
||||
],
|
||||
],
|
||||
'Student' => [
|
||||
'role' => 'student',
|
||||
'hasentries' => true,
|
||||
'expected' => null,
|
||||
],
|
||||
];
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user