Merge branch 'MDL-83901-main-v02' of https://github.com/ferranrecio/moodle
This commit is contained in:
@@ -145,7 +145,7 @@ final class overviewfactory_test extends \advanced_testcase {
|
||||
],
|
||||
'workshop' => [
|
||||
'resourcetype' => 'workshop',
|
||||
'expected' => resourceoverview::class,
|
||||
'expected' => \mod_workshop\courseformat\overview::class,
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
@@ -84,7 +84,7 @@ final class missingoverviewnotice_test extends \advanced_testcase {
|
||||
'scorm' => ['modname' => 'scorm', 'expectempty' => false],
|
||||
'url' => ['modname' => 'url', 'expectempty' => false],
|
||||
'wiki' => ['modname' => 'wiki', 'expectempty' => false],
|
||||
'workshop' => ['modname' => 'workshop', 'expectempty' => false],
|
||||
'workshop' => ['modname' => 'workshop', 'expectempty' => true],
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,236 @@
|
||||
<?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_workshop\courseformat;
|
||||
|
||||
use cm_info;
|
||||
use core_courseformat\local\overview\overviewitem;
|
||||
use core\output\action_link;
|
||||
use core\output\local\properties\text_align;
|
||||
use core\output\local\properties\button;
|
||||
use core\url;
|
||||
use stdClass;
|
||||
use workshop;
|
||||
|
||||
/**
|
||||
* Workshop overview integration.
|
||||
*
|
||||
* @package mod_workshop
|
||||
* @copyright 2025 Ferran Recio <[email protected]>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
class overview extends \core_courseformat\activityoverviewbase {
|
||||
/** @var workshop $workshop the workshop instance. */
|
||||
private workshop $workshop;
|
||||
|
||||
/** @var stdClass $activephase the active phase. */
|
||||
private stdClass $activephase;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param cm_info $cm the course module instance.
|
||||
*/
|
||||
public function __construct(
|
||||
cm_info $cm,
|
||||
) {
|
||||
global $CFG, $USER;
|
||||
|
||||
require_once($CFG->dirroot . '/mod/workshop/locallib.php');
|
||||
|
||||
parent::__construct($cm);
|
||||
$this->workshop = new workshop(
|
||||
$cm->get_instance_record(),
|
||||
$cm,
|
||||
$this->course,
|
||||
$this->context,
|
||||
);
|
||||
|
||||
$userplan = new \workshop_user_plan($this->workshop, $USER->id);
|
||||
foreach ($userplan->phases as $phase) {
|
||||
if ($phase->active) {
|
||||
$this->activephase = $phase;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[\Override]
|
||||
protected function get_grade_item_names(array $items): array {
|
||||
if (count($items) != 2) {
|
||||
return parent::get_grade_item_names($items);
|
||||
}
|
||||
$names = [];
|
||||
foreach ($items as $item) {
|
||||
$stridentifier = ($item->itemnumber == 0) ? 'overview_submission_grade' : 'overview_assessment_grade';
|
||||
$names[$item->id] = get_string($stridentifier, 'mod_workshop');
|
||||
}
|
||||
return $names;
|
||||
}
|
||||
|
||||
#[\Override]
|
||||
public function get_extra_overview_items(): array {
|
||||
return [
|
||||
'phase' => $this->get_extra_phase_overview(),
|
||||
'deadline' => $this->get_extra_deadline_overview(),
|
||||
'submissions' => $this->get_extra_submissions_overview(),
|
||||
'assessments' => $this->get_extra_assessments_overview(),
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the current phase overview item.
|
||||
*
|
||||
* @return overviewitem|null An overview item, or null if the user lacks the required capability.
|
||||
*/
|
||||
private function get_extra_phase_overview(): ?overviewitem {
|
||||
$currentphasetitle = '-';
|
||||
if ($this->activephase) {
|
||||
$currentphasetitle = $this->activephase->title;
|
||||
}
|
||||
return new overviewitem(
|
||||
name: get_string('phase', 'workshop'),
|
||||
value: $this->workshop->phase,
|
||||
content: $currentphasetitle,
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves an overview of the deadline for the workshop.
|
||||
*
|
||||
* @return overviewitem|null An overview item, or null if the current phase does not have a deadline.
|
||||
*/
|
||||
private function get_extra_deadline_overview(): ?overviewitem {
|
||||
$deadline = match ((int)$this->workshop->phase) {
|
||||
workshop::PHASE_SUBMISSION => $this->workshop->submissionend ?? 0,
|
||||
workshop::PHASE_ASSESSMENT => $this->workshop->assessmentend ?? 0,
|
||||
default => 0,
|
||||
};
|
||||
|
||||
if (empty($deadline)) {
|
||||
return new overviewitem(
|
||||
name: get_string('deadline', 'workshop'),
|
||||
value: null,
|
||||
content: '-',
|
||||
);
|
||||
}
|
||||
|
||||
return new overviewitem(
|
||||
name: get_string('deadline', 'workshop'),
|
||||
value: (int) $deadline,
|
||||
content: userdate($deadline),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves an overview of submissions for the workshop.
|
||||
*
|
||||
* @return overviewitem|null An overview item, or null if the user lacks the required capability.
|
||||
*/
|
||||
private function get_extra_submissions_overview(): ?overviewitem {
|
||||
if (!has_capability('mod/workshop:viewallsubmissions', $this->cm->context)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$submissions = $this->workshop->count_submissions();
|
||||
$total = $this->workshop->count_participants();
|
||||
|
||||
if (!$total) {
|
||||
return new overviewitem(
|
||||
name: get_string('submissions', 'workshop'),
|
||||
value: 0,
|
||||
content: '-',
|
||||
textalign: text_align::CENTER,
|
||||
);
|
||||
}
|
||||
|
||||
$content = get_string(
|
||||
'count_of_total',
|
||||
'core',
|
||||
['count' => $submissions, 'total' => $total]
|
||||
);
|
||||
|
||||
// If the current phase is submission, we can add a direct link.
|
||||
if ($this->workshop->phase == workshop::PHASE_SUBMISSION) {
|
||||
$content = new action_link(
|
||||
url: new url(
|
||||
'/mod/workshop/view.php',
|
||||
['id' => $this->cm->id],
|
||||
'workshop-viewlet-allsubmissions',
|
||||
),
|
||||
text: $content,
|
||||
attributes: ['class' => button::SECONDARY_OUTLINE->classes()],
|
||||
);
|
||||
}
|
||||
|
||||
return new overviewitem(
|
||||
name: get_string('submissions', 'workshop'),
|
||||
value: $submissions,
|
||||
content: $content,
|
||||
textalign: text_align::CENTER,
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves an overview of assessments for the workshop.
|
||||
*
|
||||
* @return overviewitem|null An overview item, or null if the user lacks the required capability.
|
||||
*/
|
||||
private function get_extra_assessments_overview(): ?overviewitem {
|
||||
global $USER;
|
||||
|
||||
if (!has_capability('mod/workshop:viewallassessments', $this->cm->context)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$assessments = $this->workshop->count_assessments(true);
|
||||
$total = $this->workshop->count_assessments(false);
|
||||
|
||||
if (!$total) {
|
||||
return new overviewitem(
|
||||
name: get_string('assessments', 'workshop'),
|
||||
value: 0,
|
||||
content: '-',
|
||||
textalign: text_align::CENTER,
|
||||
);
|
||||
}
|
||||
|
||||
$content = get_string(
|
||||
'count_of_total',
|
||||
'core',
|
||||
['count' => $assessments, 'total' => $total]
|
||||
);
|
||||
|
||||
// If the current phase is assessment, we can add a direct link.
|
||||
if ($this->workshop->phase == workshop::PHASE_ASSESSMENT) {
|
||||
$content = new action_link(
|
||||
url: new url(
|
||||
'/mod/workshop/view.php',
|
||||
['id' => $this->cm->id],
|
||||
'workshop-viewlet-gradereport',
|
||||
),
|
||||
text: $content,
|
||||
attributes: ['class' => button::SECONDARY_OUTLINE->classes()],
|
||||
);
|
||||
}
|
||||
|
||||
return new overviewitem(
|
||||
name: get_string('assessments', 'workshop'),
|
||||
value: $assessments,
|
||||
content: $content,
|
||||
textalign: text_align::CENTER,
|
||||
);
|
||||
}
|
||||
}
|
||||
+3
-63
@@ -24,68 +24,8 @@
|
||||
*/
|
||||
|
||||
require(__DIR__.'/../../config.php');
|
||||
require_once(__DIR__.'/lib.php');
|
||||
|
||||
$id = required_param('id', PARAM_INT); // course
|
||||
// For this type of page this is the course id.
|
||||
$courseid = required_param('id', PARAM_INT);
|
||||
|
||||
$course = $DB->get_record('course', array('id' => $id), '*', MUST_EXIST);
|
||||
|
||||
require_course_login($course);
|
||||
|
||||
$PAGE->set_pagelayout('incourse');
|
||||
$PAGE->set_url('/mod/workshop/index.php', array('id' => $course->id));
|
||||
$PAGE->set_title($course->fullname);
|
||||
$PAGE->set_heading($course->shortname);
|
||||
$PAGE->navbar->add(get_string('modulenameplural', 'workshop'));
|
||||
|
||||
/// Output starts here
|
||||
|
||||
echo $OUTPUT->header();
|
||||
|
||||
$params = array('context' => context_course::instance($course->id));
|
||||
$event = \mod_workshop\event\course_module_instance_list_viewed::create($params);
|
||||
$event->add_record_snapshot('course', $course);
|
||||
$event->trigger();
|
||||
|
||||
/// Get all the appropriate data
|
||||
|
||||
if (! $workshops = get_all_instances_in_course('workshop', $course)) {
|
||||
echo $OUTPUT->heading(get_string('modulenameplural', 'workshop'));
|
||||
notice(get_string('noworkshops', 'workshop'), new moodle_url('/course/view.php', array('id' => $course->id)));
|
||||
echo $OUTPUT->footer();
|
||||
die();
|
||||
}
|
||||
|
||||
$usesections = course_format_uses_sections($course->format);
|
||||
|
||||
$timenow = time();
|
||||
$strname = get_string('name');
|
||||
$table = new html_table();
|
||||
|
||||
if ($usesections) {
|
||||
$strsectionname = course_get_format($course)->get_generic_section_name();
|
||||
$table->head = array ($strsectionname, $strname);
|
||||
$table->align = array ('center', 'left');
|
||||
} else {
|
||||
$table->head = array ($strname);
|
||||
$table->align = array ('left');
|
||||
}
|
||||
|
||||
foreach ($workshops as $workshop) {
|
||||
if (empty($workshop->visible)) {
|
||||
$link = html_writer::link(new moodle_url('/mod/workshop/view.php', array('id' => $workshop->coursemodule)),
|
||||
$workshop->name, array('class' => 'dimmed'));
|
||||
} else {
|
||||
$link = html_writer::link(new moodle_url('/mod/workshop/view.php', array('id' => $workshop->coursemodule)),
|
||||
$workshop->name);
|
||||
}
|
||||
|
||||
if ($usesections) {
|
||||
$table->data[] = array(get_section_name($course, $workshop->section), $link);
|
||||
} else {
|
||||
$table->data[] = array($link);
|
||||
}
|
||||
}
|
||||
echo $OUTPUT->heading(get_string('modulenameplural', 'workshop'), 3);
|
||||
echo html_writer::table($table);
|
||||
echo $OUTPUT->footer();
|
||||
\core_courseformat\activityoverviewbase::redirect_to_overview_page($courseid, 'workshop');
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
noworkshops,mod_workshop
|
||||
@@ -108,6 +108,7 @@ $string['daysleft'] = '{$a} days left';
|
||||
$string['daystoday'] = 'today';
|
||||
$string['daystomorrow'] = 'tomorrow';
|
||||
$string['daysyesterday'] = 'yesterday';
|
||||
$string['deadline'] = 'Deadline';
|
||||
$string['deadlinesignored'] = 'Time restrictions do not apply to you';
|
||||
$string['deletesubmission'] = 'Delete submission';
|
||||
$string['editassessmentform'] = 'Edit assessment form';
|
||||
@@ -229,7 +230,6 @@ $string['nosubmissions'] = 'No submissions yet in this workshop';
|
||||
$string['nothingtoreview'] = 'Nothing to review';
|
||||
$string['notassessed'] = 'Not assessed yet';
|
||||
$string['notoverridden'] = 'Not overridden';
|
||||
$string['noworkshops'] = 'There are no workshops in this course';
|
||||
$string['noyoursubmission'] = 'You have not submitted your work yet';
|
||||
$string['nothingfound'] = 'Nothing to display';
|
||||
$string['nullgrade'] = '-';
|
||||
@@ -241,10 +241,13 @@ $string['overallfeedbackmode_0'] = 'Disabled';
|
||||
$string['overallfeedbackmode_1'] = 'Enabled and optional';
|
||||
$string['overallfeedbackmode_2'] = 'Enabled and required';
|
||||
$string['overallfeedbackmode_help'] = 'If enabled, a text field is displayed at the bottom of the assessment form. Reviewers can put the overall assessment of the submission there, or provide additional explanation of their assessment.';
|
||||
$string['overview_assessment_grade'] = 'Assessment grade';
|
||||
$string['overview_submission_grade'] = 'Submission grade';
|
||||
$string['page-mod-workshop-x'] = 'Any workshop module page';
|
||||
$string['participant'] = 'Participant';
|
||||
$string['participantrevierof'] = 'Participant is reviewer of';
|
||||
$string['participantreviewedby'] = 'Participant is reviewed by';
|
||||
$string['phase'] = 'Phase';
|
||||
$string['phaseassessment'] = 'Assessment phase';
|
||||
$string['phaseclosed'] = 'Closed';
|
||||
$string['phaseevaluation'] = 'Grading evaluation phase';
|
||||
@@ -345,6 +348,7 @@ $string['strategy_help'] = 'The grading strategy determines the assessment form
|
||||
* Rubric - A level assessment is given regarding specified criteria';
|
||||
$string['strategyhaschanged'] = 'The workshop grading strategy has changed since the form was opened for editing.';
|
||||
$string['submission'] = 'Submission';
|
||||
$string['submissions'] = 'Submissions';
|
||||
$string['submissionattachment'] = 'Attachment';
|
||||
$string['submissionby'] = 'Submission by {$a}';
|
||||
$string['submissioncontent'] = 'Submission content';
|
||||
@@ -455,3 +459,6 @@ $string['yourassessmentfor'] = 'Your assessment for {$a}';
|
||||
$string['yourgrades'] = 'Your grades';
|
||||
$string['yoursubmission'] = 'Your submission';
|
||||
$string['yoursubmissionwithassessments'] = 'Your submission with assessments';
|
||||
|
||||
// Deprecated since Moodle 5.0.
|
||||
$string['noworkshops'] = 'There are no workshops in this course';
|
||||
|
||||
@@ -774,6 +774,37 @@ class workshop {
|
||||
return $DB->count_records_sql($sql, $params);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the total number of assessments in the workshop.
|
||||
*
|
||||
* @param bool $onlygraded If true, count only graded assessments
|
||||
* @param int|null $groupid If not null, return only assessments by reviewers in the specified group
|
||||
* @return int Number of assessments
|
||||
*/
|
||||
public function count_assessments(bool $onlygraded = false, ?int $groupid = null): int {
|
||||
global $DB;
|
||||
|
||||
$params = ['workshopid' => $this->id];
|
||||
$sql = "SELECT COUNT(s.id)
|
||||
FROM {workshop_assessments} s
|
||||
JOIN {workshop_submissions} ws ON (s.submissionid = ws.id)
|
||||
JOIN {user} u ON (ws.authorid = u.id)
|
||||
JOIN {workshop} w ON (ws.workshopid = w.id)";
|
||||
|
||||
if ($groupid) {
|
||||
$sql .= " JOIN {groups_members} gm ON (gm.userid = u.id AND gm.groupid = :groupid)";
|
||||
$params['groupid'] = $groupid;
|
||||
}
|
||||
|
||||
if ($onlygraded) {
|
||||
$sql .= " WHERE s.grade IS NOT NULL AND w.id = :workshopid";
|
||||
} else {
|
||||
$sql .= " WHERE w.id = :workshopid";
|
||||
}
|
||||
|
||||
return $DB->count_records_sql($sql, $params);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns submissions from this workshop
|
||||
|
||||
@@ -0,0 +1,166 @@
|
||||
@mod @mod_workshop
|
||||
Feature: Testing overview integration in mod_workshop
|
||||
In order to summarize the workshops
|
||||
As a user
|
||||
I need to be able to see the workshop overview
|
||||
|
||||
Background:
|
||||
Given the following "users" exist:
|
||||
| username | firstname | lastname |
|
||||
| student1 | Student | 1 |
|
||||
| student2 | Student | 2 |
|
||||
| student3 | Student | 3 |
|
||||
| student4 | Student | 4 |
|
||||
| student5 | Student | 5 |
|
||||
| student6 | Student | 6 |
|
||||
| student7 | Student | 7 |
|
||||
| student8 | Student | 8 |
|
||||
| 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 |
|
||||
| student4 | C1 | student |
|
||||
| student5 | C1 | student |
|
||||
| student6 | C1 | student |
|
||||
| student7 | C1 | student |
|
||||
| student8 | C1 | student |
|
||||
| teacher1 | C1 | editingteacher |
|
||||
And the following "activities" exist:
|
||||
| activity | name | course | idnumber | submissiontypetext | submissiontypefile | grade | gradinggrade | gradedecimals | overallfeedbackmethod |latesubmissions | submisstionstart | submissionend |
|
||||
| workshop | Activity 1 | C1 | workshop1 | 2 | 1 | 100 | 5 | 1 | 2 |1 | ##1 Jan 2018 08:00## | ##1 Jan 2040 08:00## |
|
||||
| workshop | Activity 2 | C1 | workshop1 | 2 | 1 | 100 | 5 | 1 | 2 |1 | ##1 Jan 2018 08:00## | ##1 Jan 2040 08:00## |
|
||||
|
||||
Scenario: The workshop overview report should generate log events
|
||||
Given I am on the "Course 1" "course > activities > workshop" 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 'workshop'"
|
||||
|
||||
@javascript
|
||||
Scenario: Students can see relevant columns in the workshop overview
|
||||
# Workshop is not compatible with grade generators (hopefully someday).
|
||||
Given I am on the "Course 1" "grades > Grader report > View" page logged in as "teacher1"
|
||||
And I turn editing mode on
|
||||
And I change window size to "large"
|
||||
And I click on "Activity 1 (submission)" "core_grades > grade_actions" in the "Student 1" "table_row"
|
||||
And I choose "Edit grade" in the open action menu
|
||||
And I set the following fields to these values:
|
||||
| Overridden | 1 |
|
||||
| Final grade | 10 |
|
||||
And I press "Save changes"
|
||||
And I click on "Activity 2 (assessment)" "core_grades > grade_actions" in the "Student 1" "table_row"
|
||||
And I choose "Edit grade" in the open action menu
|
||||
And I set the following fields to these values:
|
||||
| Overridden | 1 |
|
||||
| Final grade | 20 |
|
||||
And I press "Save changes"
|
||||
And I change window size to "medium"
|
||||
And I am on the "Activity 1" "workshop activity" page
|
||||
And I change phase in workshop "Activity 1" to "Submission phase"
|
||||
When I am on the "Course 1" "course > activities > workshop" page logged in as "student1"
|
||||
# Check columns.
|
||||
Then I should see "Name" in the "workshop_overview_collapsible" "region"
|
||||
And I should see "Phase" in the "workshop_overview_collapsible" "region"
|
||||
And I should see "Deadline" in the "workshop_overview_collapsible" "region"
|
||||
And I should see "Assessment grade" in the "workshop_overview_collapsible" "region"
|
||||
And I should see "Submission grade" in the "workshop_overview_collapsible" "region"
|
||||
# Check phase.
|
||||
And I should see "Submission phase" in the "Activity 1" "table_row"
|
||||
And I should see "Setup phase" in the "Activity 2" "table_row"
|
||||
# Cheack Deadline.
|
||||
And I should see "1 January 2040" in the "Activity 1" "table_row"
|
||||
And I should see "-" in the "Activity 2" "table_row"
|
||||
# Check Grades.
|
||||
And I should see "10.00" in the "Activity 1" "table_row"
|
||||
And I should see "-" in the "Activity 1" "table_row"
|
||||
And I should see "-" in the "Activity 2" "table_row"
|
||||
# The worksup assessment grade is normalized to 5.00.
|
||||
And I should see "5.00" in the "Activity 2" "table_row"
|
||||
|
||||
Scenario: Teachers can see relevant columns in the workshop overview
|
||||
Given I log in as "teacher1"
|
||||
And I am on the "C1" course page logged in as teacher1
|
||||
And I edit assessment form in workshop "Activity 1" as:
|
||||
| id_description__idx_0_editor | Aspect1 |
|
||||
| id_description__idx_1_editor | |
|
||||
| id_description__idx_2_editor | |
|
||||
And I change phase in workshop "Activity 1" to "Submission phase"
|
||||
# Change activity 2 to submission phase to see due date.
|
||||
And I am on the "Activity 2" "workshop activity" page
|
||||
And I change phase in workshop "Activity 2" to "Submission phase"
|
||||
# student1 submits
|
||||
And I am on the "Activity 1" "workshop activity" page logged in as student1
|
||||
And I add a submission in workshop "Activity 1" as:
|
||||
| Title | Submission1 |
|
||||
| Submission content | Some content |
|
||||
# teacher1 allocates reviewers and changes the phase to assessment
|
||||
When I am on the "Activity 1" "workshop activity" page logged in as teacher1
|
||||
And I allocate submissions in workshop "Activity 1" as:
|
||||
| Participant | Reviewer |
|
||||
| Student 1 | Student 2 |
|
||||
| Student 1 | Student 3 |
|
||||
| Student 1 | Student 4 |
|
||||
And I am on the "Activity 1" "workshop activity" page
|
||||
And I change phase in workshop "Activity 1" to "Assessment phase"
|
||||
# student2 assesses work of student1
|
||||
And I am on the "Activity 1" "workshop activity" page logged in as student2
|
||||
And I assess submission "Student 1" in workshop "Activity 1" as:
|
||||
| grade__idx_0 | 10 / 10 |
|
||||
| peercomment__idx_0 | Amazing |
|
||||
| Feedback for the author | Good work |
|
||||
# student3 assesses work of student1
|
||||
And I am on the "Activity 1" "workshop activity" page logged in as student3
|
||||
And I assess submission "Student 1" in workshop "Activity 1" as:
|
||||
| grade__idx_0 | 10 / 10 |
|
||||
| peercomment__idx_0 | Amazing |
|
||||
| Feedback for the author | Good work |
|
||||
# student4 assesses work of student1
|
||||
And I am on the "Activity 1" "workshop activity" page logged in as student4
|
||||
And I assess submission "Student 1" in workshop "Activity 1" as:
|
||||
| grade__idx_0 | 6 / 10 |
|
||||
| peercomment__idx_0 | You can do better |
|
||||
| Feedback for the author | Good work |
|
||||
# teacher1 makes sure he can see all peer grades and changes to grading evaluation phase
|
||||
And I am on the "Activity 1" "workshop activity" page logged in as teacher1
|
||||
And I change phase in workshop "Activity 1" to "Grading evaluation phase"
|
||||
And I press "Re-calculate grades"
|
||||
# Now, the test itself.
|
||||
When I am on the "Course 1" "course > activities > workshop" page logged in as "teacher1"
|
||||
# Check columns.
|
||||
Then I should see "Name" in the "workshop_overview_collapsible" "region"
|
||||
And I should see "Phase" in the "workshop_overview_collapsible" "region"
|
||||
And I should see "Deadline" in the "workshop_overview_collapsible" "region"
|
||||
And I should see "Submissions" in the "workshop_overview_collapsible" "region"
|
||||
And I should see "Assessments" in the "workshop_overview_collapsible" "region"
|
||||
# Check phase.
|
||||
And I should see "Grading evaluation phase" in the "Activity 1" "table_row"
|
||||
And I should see "Submission phase" in the "Activity 2" "table_row"
|
||||
# Cheack Deadline.
|
||||
And I should see "-" in the "Activity 1" "table_row"
|
||||
And I should see "1 January 2040" in the "Activity 2" "table_row"
|
||||
# Check Submissions.
|
||||
And I should see "1 of 8" in the "Activity 1" "table_row"
|
||||
And I should see "0 of 8" in the "Activity 2" "table_row"
|
||||
# Check Assessments.
|
||||
And I should see "3 of 3" in the "Activity 1" "table_row"
|
||||
And I should see "-" in the "Activity 2" "table_row"
|
||||
|
||||
@javascript
|
||||
Scenario: The workshop 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 "Workshops" "link" in the "Activities" "block"
|
||||
Then I should see "View all the activities in this course"
|
||||
And I should see "Name" in the "workshop_overview_collapsible" "region"
|
||||
And I should see "Phase" in the "workshop_overview_collapsible" "region"
|
||||
And I should see "Submissions" in the "workshop_overview_collapsible" "region"
|
||||
And I should see "Assessments" in the "workshop_overview_collapsible" "region"
|
||||
@@ -0,0 +1,636 @@
|
||||
<?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_workshop\courseformat;
|
||||
|
||||
use core_courseformat\local\overview\overviewfactory;
|
||||
|
||||
/**
|
||||
* Tests for Workshop overview integration.
|
||||
*
|
||||
* @covers \mod_workshop\course\overview
|
||||
* @package mod_workshop
|
||||
* @category test
|
||||
* @copyright 2025 Ferran Recio <[email protected]>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
final class overview_test extends \advanced_testcase {
|
||||
#[\Override]
|
||||
public static function setUpBeforeClass(): void {
|
||||
global $CFG;
|
||||
require_once($CFG->dirroot . '/mod/workshop/locallib.php');
|
||||
parent::setUpBeforeClass();
|
||||
}
|
||||
|
||||
/**
|
||||
* Test get_grade_item_names method.
|
||||
*
|
||||
* @dataProvider data_provider_get_grade_item_names
|
||||
* @covers ::get_grade_item_names
|
||||
* @param string $user
|
||||
* @param bool $expectempty
|
||||
* @param bool $hassubmission
|
||||
* @param bool $hasassesment
|
||||
*/
|
||||
public function test_get_grade_item_names(
|
||||
string $user,
|
||||
bool $expectempty,
|
||||
bool $hassubmission,
|
||||
bool $hasassesment,
|
||||
): void {
|
||||
$this->resetAfterTest();
|
||||
$this->setAdminUser();
|
||||
|
||||
$course = $this->getDataGenerator()->create_course();
|
||||
$teacher = $this->getDataGenerator()->create_and_enrol($course, 'teacher');
|
||||
$student = $this->getDataGenerator()->create_and_enrol($course, 'student');
|
||||
|
||||
$activity = $this->getDataGenerator()->create_module(
|
||||
'workshop',
|
||||
['course' => $course->id],
|
||||
);
|
||||
$cm = get_fast_modinfo($course)->get_cm($activity->cmid);
|
||||
|
||||
// Set up a generator to create content.
|
||||
/** @var \mod_workshop_generator $generator */
|
||||
$generator = $this->getDataGenerator()->get_plugin_generator('mod_workshop');
|
||||
|
||||
// Add grading.
|
||||
$workshopitems = array_values(
|
||||
\grade_item::fetch_all([
|
||||
'itemtype' => 'mod',
|
||||
'itemmodule' => 'workshop',
|
||||
'iteminstance' => (int) $activity->id,
|
||||
'courseid' => $course->id,
|
||||
['grade' => 100.0],
|
||||
])
|
||||
);
|
||||
|
||||
// Workshop stores in number 1 the assessment grade and in number 0 the submission grade.
|
||||
$gradeitems = [];
|
||||
foreach ($workshopitems as $workshopitem) {
|
||||
if ($workshopitem->itemnumber == 0) {
|
||||
$gradeitems['submission'] = $workshopitem;
|
||||
} else {
|
||||
$gradeitems['assessment'] = $workshopitem;
|
||||
}
|
||||
}
|
||||
|
||||
$expectedsubmissions = '-';
|
||||
if ($hassubmission) {
|
||||
$submissionid = $generator->create_submission(
|
||||
$activity->id,
|
||||
$student->id,
|
||||
['title' => 'My custom title', 'grade' => 85.00000],
|
||||
);
|
||||
$gradegrade = new \grade_grade();
|
||||
$gradegrade->itemid = $gradeitems['submission']->id;
|
||||
$gradegrade->userid = (int) $student->id;
|
||||
$gradegrade->rawgrade = 77;
|
||||
$gradegrade->finalgrade = 77;
|
||||
$gradegrade->insert();
|
||||
$expectedsubmissions = '77.00000';
|
||||
}
|
||||
|
||||
$expectedassessments = '-';
|
||||
if ($hasassesment) {
|
||||
$generator->create_assessment(
|
||||
$submissionid,
|
||||
$student->id,
|
||||
['weight' => 3, 'grade' => 95.00000],
|
||||
);
|
||||
$gradegrade = new \grade_grade();
|
||||
$gradegrade->itemid = $gradeitems['assessment']->id;
|
||||
$gradegrade->userid = (int) $student->id;
|
||||
$gradegrade->rawgrade = 88;
|
||||
$gradegrade->finalgrade = 88;
|
||||
$gradegrade->insert();
|
||||
$expectedassessments = '88.00000';
|
||||
}
|
||||
|
||||
$currentuser = ($user == 'teacher') ? $teacher : $student;
|
||||
$this->setUser($currentuser);
|
||||
|
||||
$items = overviewfactory::create($cm)->get_grades_overviews();
|
||||
|
||||
// Students should not see item.
|
||||
if ($expectempty) {
|
||||
$this->assertEmpty($items);
|
||||
return;
|
||||
}
|
||||
|
||||
$this->assertEquals(get_string('overview_submission_grade', 'mod_workshop'), $items[0]->get_name());
|
||||
$this->assertEquals($expectedsubmissions, $items[0]->get_value());
|
||||
|
||||
$this->assertEquals(get_string('overview_assessment_grade', 'mod_workshop'), $items[1]->get_name());
|
||||
$this->assertEquals($expectedassessments, $items[1]->get_value());
|
||||
}
|
||||
|
||||
/**
|
||||
* Data provider for test_get_grade_item_names.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function data_provider_get_grade_item_names(): array {
|
||||
return [
|
||||
'student with submissions' => [
|
||||
'user' => 'student',
|
||||
'expectempty' => false,
|
||||
'hassubmission' => true,
|
||||
'hasassesment' => false,
|
||||
],
|
||||
'student with assessments' => [
|
||||
'user' => 'student',
|
||||
'expectempty' => false,
|
||||
'hassubmission' => true,
|
||||
'hasassesment' => true,
|
||||
],
|
||||
'teacher' => [
|
||||
'user' => 'teacher',
|
||||
'expectempty' => true,
|
||||
'hassubmission' => false,
|
||||
'hasassesment' => false,
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Test get_extra_phase_overview method.
|
||||
*
|
||||
* @covers ::get_extra_phase_overview
|
||||
* @dataProvider data_provider_get_extra_phase_overview
|
||||
* @param string $user
|
||||
* @param int $currentphase
|
||||
*/
|
||||
public function test_get_extra_phase_overview(string $user, int $currentphase): void {
|
||||
$this->resetAfterTest();
|
||||
$this->setAdminUser();
|
||||
|
||||
$course = $this->getDataGenerator()->create_course();
|
||||
$teacher = $this->getDataGenerator()->create_and_enrol($course, 'teacher');
|
||||
$student = $this->getDataGenerator()->create_and_enrol($course, 'student');
|
||||
|
||||
$activity = $this->getDataGenerator()->create_module(
|
||||
'workshop',
|
||||
['course' => $course->id],
|
||||
);
|
||||
$cm = get_fast_modinfo($course)->get_cm($activity->cmid);
|
||||
|
||||
$manager = new \workshop($activity, $cm, $course, $cm->context);
|
||||
$manager->switch_phase($currentphase);
|
||||
|
||||
$currentuser = ($user == 'teacher') ? $teacher : $student;
|
||||
$this->setUser($currentuser);
|
||||
|
||||
$overview = overviewfactory::create($cm);
|
||||
$reflection = new \ReflectionClass($overview);
|
||||
$method = $reflection->getMethod('get_extra_phase_overview');
|
||||
$method->setAccessible(true);
|
||||
$item = $method->invoke($overview);
|
||||
|
||||
$this->assertEquals(get_string('phase', 'mod_workshop'), $item->get_name());
|
||||
$this->assertEquals($currentphase, $item->get_value());
|
||||
}
|
||||
|
||||
/**
|
||||
* Data provider for test_get_extra_phase_overview.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function data_provider_get_extra_phase_overview(): array {
|
||||
return [
|
||||
'teacher setup phase' => [
|
||||
'user' => 'teacher',
|
||||
'currentphase' => \workshop::PHASE_SETUP,
|
||||
],
|
||||
'student setup phase' => [
|
||||
'user' => 'student',
|
||||
'currentphase' => \workshop::PHASE_SETUP,
|
||||
],
|
||||
'teacher submission phase' => [
|
||||
'user' => 'teacher',
|
||||
'currentphase' => \workshop::PHASE_SUBMISSION,
|
||||
],
|
||||
'student submission phase' => [
|
||||
'user' => 'student',
|
||||
'currentphase' => \workshop::PHASE_SUBMISSION,
|
||||
],
|
||||
'teacher assessment phase' => [
|
||||
'user' => 'teacher',
|
||||
'currentphase' => \workshop::PHASE_ASSESSMENT,
|
||||
],
|
||||
'student assessment phase' => [
|
||||
'user' => 'student',
|
||||
'currentphase' => \workshop::PHASE_ASSESSMENT,
|
||||
],
|
||||
'teacher evaluation phase' => [
|
||||
'user' => 'teacher',
|
||||
'currentphase' => \workshop::PHASE_EVALUATION,
|
||||
],
|
||||
'student evaluation phase' => [
|
||||
'user' => 'student',
|
||||
'currentphase' => \workshop::PHASE_EVALUATION,
|
||||
],
|
||||
'teacher closed phase' => [
|
||||
'user' => 'teacher',
|
||||
'currentphase' => \workshop::PHASE_CLOSED,
|
||||
],
|
||||
'student closed phase' => [
|
||||
'user' => 'student',
|
||||
'currentphase' => \workshop::PHASE_CLOSED,
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Test get_extra_deadline_overview method.
|
||||
*
|
||||
* @covers ::get_extra_deadline_overview
|
||||
* @dataProvider data_provider_get_extra_deadline_overview
|
||||
* @param string $user
|
||||
* @param int $currentphase
|
||||
* @param int $submissionend
|
||||
* @param int $assessmentend
|
||||
* @param int|null $expectedincrement null if the item should be null.
|
||||
*/
|
||||
public function test_get_extra_deadline_overview(
|
||||
string $user,
|
||||
int $currentphase,
|
||||
int $submissionend,
|
||||
int $assessmentend,
|
||||
?int $expectedincrement,
|
||||
): void {
|
||||
$this->resetAfterTest();
|
||||
$this->setAdminUser();
|
||||
|
||||
$course = $this->getDataGenerator()->create_course();
|
||||
$teacher = $this->getDataGenerator()->create_and_enrol($course, 'teacher');
|
||||
$student = $this->getDataGenerator()->create_and_enrol($course, 'student');
|
||||
|
||||
$current = $this->mock_clock_with_frozen()->time();
|
||||
|
||||
$activity = $this->getDataGenerator()->create_module(
|
||||
'workshop',
|
||||
[
|
||||
'course' => $course->id,
|
||||
'submissionend' => $current + $submissionend,
|
||||
'assessmentend' => $current + $assessmentend,
|
||||
],
|
||||
);
|
||||
$cm = get_fast_modinfo($course)->get_cm($activity->cmid);
|
||||
|
||||
$manager = new \workshop($activity, $cm, $course, $cm->context);
|
||||
$manager->switch_phase($currentphase);
|
||||
|
||||
$currentuser = ($user == 'teacher') ? $teacher : $student;
|
||||
$this->setUser($currentuser);
|
||||
|
||||
$overview = overviewfactory::create($cm);
|
||||
$reflection = new \ReflectionClass($overview);
|
||||
$method = $reflection->getMethod('get_extra_deadline_overview');
|
||||
$method->setAccessible(true);
|
||||
$item = $method->invoke($overview);
|
||||
|
||||
$this->assertEquals(get_string('deadline', 'mod_workshop'), $item->get_name());
|
||||
|
||||
if ($expectedincrement === null) {
|
||||
$this->assertNull($item->get_value());
|
||||
return;
|
||||
}
|
||||
|
||||
$this->assertEquals($current + $expectedincrement, $item->get_value());
|
||||
}
|
||||
|
||||
/**
|
||||
* Data provider for test_get_extra_phase_overview.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function data_provider_get_extra_deadline_overview(): array {
|
||||
$submissionend = 3600;
|
||||
$assessmentend = 7200;
|
||||
return [
|
||||
'teacher setup phase' => [
|
||||
'user' => 'teacher',
|
||||
'currentphase' => \workshop::PHASE_SETUP,
|
||||
'submissionend' => $submissionend,
|
||||
'assessmentend' => $assessmentend,
|
||||
'expectedincrement' => null,
|
||||
],
|
||||
'student setup phase' => [
|
||||
'user' => 'student',
|
||||
'currentphase' => \workshop::PHASE_SETUP,
|
||||
'submissionend' => $submissionend,
|
||||
'assessmentend' => $assessmentend,
|
||||
'expectedincrement' => null,
|
||||
],
|
||||
'teacher submission phase' => [
|
||||
'user' => 'teacher',
|
||||
'currentphase' => \workshop::PHASE_SUBMISSION,
|
||||
'submissionend' => $submissionend,
|
||||
'assessmentend' => $assessmentend,
|
||||
'expectedincrement' => $submissionend,
|
||||
],
|
||||
'student submission phase' => [
|
||||
'user' => 'student',
|
||||
'currentphase' => \workshop::PHASE_SUBMISSION,
|
||||
'submissionend' => $submissionend,
|
||||
'assessmentend' => $assessmentend,
|
||||
'expectedincrement' => $submissionend,
|
||||
],
|
||||
'teacher assessment phase' => [
|
||||
'user' => 'teacher',
|
||||
'currentphase' => \workshop::PHASE_ASSESSMENT,
|
||||
'submissionend' => $submissionend,
|
||||
'assessmentend' => $assessmentend,
|
||||
'expectedincrement' => $assessmentend,
|
||||
],
|
||||
'student assessment phase' => [
|
||||
'user' => 'student',
|
||||
'currentphase' => \workshop::PHASE_ASSESSMENT,
|
||||
'submissionend' => $submissionend,
|
||||
'assessmentend' => $assessmentend,
|
||||
'expectedincrement' => $assessmentend,
|
||||
],
|
||||
'teacher evaluation phase' => [
|
||||
'user' => 'teacher',
|
||||
'currentphase' => \workshop::PHASE_EVALUATION,
|
||||
'submissionend' => $submissionend,
|
||||
'assessmentend' => $assessmentend,
|
||||
'expectedincrement' => null,
|
||||
],
|
||||
'student evaluation phase' => [
|
||||
'user' => 'student',
|
||||
'currentphase' => \workshop::PHASE_EVALUATION,
|
||||
'submissionend' => $submissionend,
|
||||
'assessmentend' => $assessmentend,
|
||||
'expectedincrement' => null,
|
||||
],
|
||||
'teacher closed phase' => [
|
||||
'user' => 'teacher',
|
||||
'currentphase' => \workshop::PHASE_CLOSED,
|
||||
'submissionend' => $submissionend,
|
||||
'assessmentend' => $assessmentend,
|
||||
'expectedincrement' => null,
|
||||
],
|
||||
'student closed phase' => [
|
||||
'user' => 'student',
|
||||
'currentphase' => \workshop::PHASE_CLOSED,
|
||||
'submissionend' => $submissionend,
|
||||
'assessmentend' => $assessmentend,
|
||||
'expectedincrement' => null,
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Test get_extra_submissions_overview and get_extra_assessments_overview methods.
|
||||
*
|
||||
* @covers ::get_extra_submissions_overview
|
||||
* @covers ::get_extra_assessments_overview
|
||||
* @dataProvider data_provider_get_extra_submissions_overview
|
||||
* @param string $user
|
||||
* @param int $currentphase
|
||||
* @param bool $hasstudentactivity
|
||||
* @param bool $expectnull
|
||||
*/
|
||||
public function test_get_extra_submissions_overview(
|
||||
string $user,
|
||||
int $currentphase,
|
||||
bool $hasstudentactivity,
|
||||
bool $expectnull,
|
||||
): void {
|
||||
$this->resetAfterTest();
|
||||
$this->setAdminUser();
|
||||
|
||||
$course = $this->getDataGenerator()->create_course();
|
||||
$teacher = $this->getDataGenerator()->create_and_enrol($course, 'teacher');
|
||||
$student = $this->getDataGenerator()->create_and_enrol($course, 'student');
|
||||
$student2 = $this->getDataGenerator()->create_and_enrol($course, 'student');
|
||||
|
||||
$activity = $this->getDataGenerator()->create_module(
|
||||
'workshop',
|
||||
['course' => $course->id],
|
||||
);
|
||||
$cm = get_fast_modinfo($course)->get_cm($activity->cmid);
|
||||
|
||||
// Set up a generator to create content.
|
||||
/** @var \mod_workshop_generator $generator */
|
||||
$generator = $this->getDataGenerator()->get_plugin_generator('mod_workshop');
|
||||
|
||||
// Add grading.
|
||||
$workshopitems = array_values(
|
||||
\grade_item::fetch_all([
|
||||
'itemtype' => 'mod',
|
||||
'itemmodule' => 'workshop',
|
||||
'iteminstance' => (int) $activity->id,
|
||||
'courseid' => $course->id,
|
||||
['grade' => 100.0],
|
||||
])
|
||||
);
|
||||
|
||||
// Worksop stores un number 1 the assessment grade and in number 0 the submission grade.
|
||||
foreach ($workshopitems as $workshopitem) {
|
||||
if ($workshopitem->itemnumber == 0) {
|
||||
$gradeitems['submission'] = $workshopitem;
|
||||
} else {
|
||||
$gradeitems['assessment'] = $workshopitem;
|
||||
}
|
||||
}
|
||||
|
||||
if ($hasstudentactivity) {
|
||||
// Create some submissions.
|
||||
$submissionid = $generator->create_submission(
|
||||
$activity->id,
|
||||
$student->id,
|
||||
['title' => 'My custom title', 'grade' => 85.00000],
|
||||
);
|
||||
$generator->create_submission(
|
||||
$activity->id,
|
||||
$student2->id,
|
||||
['title' => 'My custom title', 'grade' => 65.00000],
|
||||
);
|
||||
// Assess one submission.
|
||||
$generator->create_assessment(
|
||||
$submissionid,
|
||||
$student->id,
|
||||
['weight' => 3, 'grade' => 95.00000],
|
||||
);
|
||||
}
|
||||
|
||||
$manager = new \workshop($activity, $cm, $course, $cm->context);
|
||||
$manager->switch_phase($currentphase);
|
||||
|
||||
$currentuser = ($user == 'teacher') ? $teacher : $student;
|
||||
$this->setUser($currentuser);
|
||||
|
||||
$overview = overviewfactory::create($cm);
|
||||
$reflection = new \ReflectionClass($overview);
|
||||
|
||||
$method = $reflection->getMethod('get_extra_submissions_overview');
|
||||
$method->setAccessible(true);
|
||||
$itemsubmissions = $method->invoke($overview);
|
||||
|
||||
$method = $reflection->getMethod('get_extra_assessments_overview');
|
||||
$method->setAccessible(true);
|
||||
$itemassessment = $method->invoke($overview);
|
||||
|
||||
if ($expectnull) {
|
||||
$this->assertNull($itemsubmissions);
|
||||
$this->assertNull($itemassessment);
|
||||
return;
|
||||
}
|
||||
|
||||
$this->assertEquals(get_string('submissions', 'mod_workshop'), $itemsubmissions->get_name());
|
||||
$expected = ($hasstudentactivity) ? 2 : 0;
|
||||
$this->assertEquals($expected, $itemsubmissions->get_value());
|
||||
|
||||
$this->assertEquals(get_string('assessments', 'mod_workshop'), $itemassessment->get_name());
|
||||
$expected = ($hasstudentactivity) ? 1 : 0;
|
||||
$this->assertEquals($expected, $itemassessment->get_value());
|
||||
}
|
||||
|
||||
/**
|
||||
* Data provider for test_get_extra_submissions_overview.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function data_provider_get_extra_submissions_overview(): array {
|
||||
return [
|
||||
'teacher setup phase without activity' => [
|
||||
'user' => 'teacher',
|
||||
'currentphase' => \workshop::PHASE_SETUP,
|
||||
'hasstudentactivity' => false,
|
||||
'expectnull' => false,
|
||||
],
|
||||
'student setup phase without activity' => [
|
||||
'user' => 'student',
|
||||
'currentphase' => \workshop::PHASE_SETUP,
|
||||
'hasstudentactivity' => false,
|
||||
'expectnull' => true,
|
||||
],
|
||||
'teacher submission phase without activity' => [
|
||||
'user' => 'teacher',
|
||||
'currentphase' => \workshop::PHASE_SUBMISSION,
|
||||
'hasstudentactivity' => false,
|
||||
'expectnull' => false,
|
||||
],
|
||||
'student submission phase without activity' => [
|
||||
'user' => 'student',
|
||||
'currentphase' => \workshop::PHASE_SUBMISSION,
|
||||
'hasstudentactivity' => false,
|
||||
'expectnull' => true,
|
||||
],
|
||||
'teacher assessment phase without activity' => [
|
||||
'user' => 'teacher',
|
||||
'currentphase' => \workshop::PHASE_ASSESSMENT,
|
||||
'hasstudentactivity' => false,
|
||||
'expectnull' => false,
|
||||
],
|
||||
'student assessment phase without activity' => [
|
||||
'user' => 'student',
|
||||
'currentphase' => \workshop::PHASE_ASSESSMENT,
|
||||
'hasstudentactivity' => false,
|
||||
'expectnull' => true,
|
||||
],
|
||||
'teacher evaluation phase without activity' => [
|
||||
'user' => 'teacher',
|
||||
'currentphase' => \workshop::PHASE_EVALUATION,
|
||||
'hasstudentactivity' => false,
|
||||
'expectnull' => false,
|
||||
],
|
||||
'student evaluation phase without activity' => [
|
||||
'user' => 'student',
|
||||
'currentphase' => \workshop::PHASE_EVALUATION,
|
||||
'hasstudentactivity' => false,
|
||||
'expectnull' => true,
|
||||
],
|
||||
'teacher closed phase without activity' => [
|
||||
'user' => 'teacher',
|
||||
'currentphase' => \workshop::PHASE_CLOSED,
|
||||
'hasstudentactivity' => false,
|
||||
'expectnull' => false,
|
||||
],
|
||||
'student closed phase without activity' => [
|
||||
'user' => 'student',
|
||||
'currentphase' => \workshop::PHASE_CLOSED,
|
||||
'hasstudentactivity' => false,
|
||||
'expectnull' => true,
|
||||
],
|
||||
// Tests with assessments.
|
||||
'teacher setup phase with activity' => [
|
||||
'user' => 'teacher',
|
||||
'currentphase' => \workshop::PHASE_SETUP,
|
||||
'hasstudentactivity' => true,
|
||||
'expectnull' => false,
|
||||
],
|
||||
'student setup phase with activity' => [
|
||||
'user' => 'student',
|
||||
'currentphase' => \workshop::PHASE_SETUP,
|
||||
'hasstudentactivity' => true,
|
||||
'expectnull' => true,
|
||||
],
|
||||
'teacher submission phase with activity' => [
|
||||
'user' => 'teacher',
|
||||
'currentphase' => \workshop::PHASE_SUBMISSION,
|
||||
'hasstudentactivity' => true,
|
||||
'expectnull' => false,
|
||||
],
|
||||
'student submission phase with activity' => [
|
||||
'user' => 'student',
|
||||
'currentphase' => \workshop::PHASE_SUBMISSION,
|
||||
'hasstudentactivity' => true,
|
||||
'expectnull' => true,
|
||||
],
|
||||
'teacher assessment phase with activity' => [
|
||||
'user' => 'teacher',
|
||||
'currentphase' => \workshop::PHASE_ASSESSMENT,
|
||||
'hasstudentactivity' => true,
|
||||
'expectnull' => false,
|
||||
],
|
||||
'student assessment phase with activity' => [
|
||||
'user' => 'student',
|
||||
'currentphase' => \workshop::PHASE_ASSESSMENT,
|
||||
'hasstudentactivity' => true,
|
||||
'expectnull' => true,
|
||||
],
|
||||
'teacher evaluation phase with activity' => [
|
||||
'user' => 'teacher',
|
||||
'currentphase' => \workshop::PHASE_EVALUATION,
|
||||
'hasstudentactivity' => true,
|
||||
'expectnull' => false,
|
||||
],
|
||||
'student evaluation phase with activity' => [
|
||||
'user' => 'student',
|
||||
'currentphase' => \workshop::PHASE_EVALUATION,
|
||||
'hasstudentactivity' => true,
|
||||
'expectnull' => true,
|
||||
],
|
||||
'teacher closed phase with activity' => [
|
||||
'user' => 'teacher',
|
||||
'currentphase' => \workshop::PHASE_CLOSED,
|
||||
'hasstudentactivity' => true,
|
||||
'expectnull' => false,
|
||||
],
|
||||
'student closed phase with activity' => [
|
||||
'user' => 'student',
|
||||
'currentphase' => \workshop::PHASE_CLOSED,
|
||||
'hasstudentactivity' => true,
|
||||
'expectnull' => true,
|
||||
],
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -867,4 +867,101 @@ final class locallib_test extends \advanced_testcase {
|
||||
|
||||
return $initialbarprefs;
|
||||
}
|
||||
|
||||
/**
|
||||
* Test count_submissions and count_assessments methods.
|
||||
*
|
||||
* @covers \workshop::count_submissions
|
||||
* @covers \workshop::count_assessments
|
||||
*/
|
||||
public function test_count_submissions_count_assessments(): void {
|
||||
$this->resetAfterTest();
|
||||
$this->setAdminUser();
|
||||
|
||||
$course = $this->getDataGenerator()->create_course();
|
||||
$group1 = $this->getDataGenerator()->create_group(['courseid' => $course->id]);
|
||||
$group2 = $this->getDataGenerator()->create_group(['courseid' => $course->id]);
|
||||
$student1 = $this->getDataGenerator()->create_and_enrol($course, 'student');
|
||||
$student2 = $this->getDataGenerator()->create_and_enrol($course, 'student');
|
||||
$student3 = $this->getDataGenerator()->create_and_enrol($course, 'student');
|
||||
$student4 = $this->getDataGenerator()->create_and_enrol($course, 'student');
|
||||
|
||||
groups_add_member($group1, $student1);
|
||||
groups_add_member($group1, $student3);
|
||||
groups_add_member($group2, $student2);
|
||||
|
||||
$activity = $this->getDataGenerator()->create_module(
|
||||
'workshop',
|
||||
['course' => $course->id , 'groupmode' => SEPARATEGROUPS],
|
||||
);
|
||||
$cm = get_fast_modinfo($course)->get_cm($activity->cmid);
|
||||
|
||||
// Set up a generator to create content.
|
||||
/** @var \mod_workshop_generator $generator */
|
||||
$generator = $this->getDataGenerator()->get_plugin_generator('mod_workshop');
|
||||
|
||||
// Create some submissions.
|
||||
$submission1id = $generator->create_submission(
|
||||
$activity->id,
|
||||
$student1->id,
|
||||
['title' => 'My custom title', 'grade' => 85.00000],
|
||||
);
|
||||
$submission2id = $generator->create_submission(
|
||||
$activity->id,
|
||||
$student2->id,
|
||||
['title' => 'My custom title', 'grade' => null],
|
||||
);
|
||||
$submission3id = $generator->create_submission(
|
||||
$activity->id,
|
||||
$student3->id,
|
||||
['title' => 'My custom title', 'grade' => null],
|
||||
);
|
||||
$submission4id = $generator->create_submission(
|
||||
$activity->id,
|
||||
$student4->id,
|
||||
['title' => 'My custom title', 'grade' => null],
|
||||
);
|
||||
// Assess one submission.
|
||||
$generator->create_assessment(
|
||||
$submission1id,
|
||||
$student1->id,
|
||||
['weight' => 3, 'grade' => 95.00000],
|
||||
);
|
||||
$generator->create_assessment(
|
||||
$submission2id,
|
||||
$student2->id,
|
||||
['weight' => 3, 'grade' => null],
|
||||
);
|
||||
$generator->create_assessment(
|
||||
$submission3id,
|
||||
$student3->id,
|
||||
['weight' => 3, 'grade' => null],
|
||||
);
|
||||
$generator->create_assessment(
|
||||
$submission4id,
|
||||
$student4->id,
|
||||
['weight' => 3, 'grade' => 35.00000],
|
||||
);
|
||||
|
||||
$manager = new workshop($activity, $cm, $course, $cm->context);
|
||||
|
||||
$this->assertEquals(4, $manager->count_submissions());
|
||||
$this->assertEquals(4, $manager->count_submissions('all'));
|
||||
$this->assertEquals(1, $manager->count_submissions($student1->id));
|
||||
$this->assertEquals(1, $manager->count_submissions($student2->id));
|
||||
|
||||
$this->assertEquals(2, $manager->count_submissions('all', $group1->id));
|
||||
$this->assertEquals(1, $manager->count_submissions('all', $group2->id));
|
||||
$this->assertEquals(1, $manager->count_submissions($student1->id, $group1->id));
|
||||
$this->assertEquals(0, $manager->count_submissions($student2->id, $group1->id));
|
||||
|
||||
$this->assertEquals(4, $manager->count_assessments());
|
||||
$this->assertEquals(2, $manager->count_assessments(true));
|
||||
|
||||
$this->assertEquals(2, $manager->count_assessments(false, $group1->id));
|
||||
$this->assertEquals(1, $manager->count_assessments(true, $group1->id));
|
||||
|
||||
$this->assertEquals(1, $manager->count_assessments(false, $group2->id));
|
||||
$this->assertEquals(0, $manager->count_assessments(true, $group2->id));
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user