Skip to content

Commit

Permalink
StudentQuiz: Throw 'invalidcomment' error when commenting on the ques…
Browse files Browse the repository at this point in the history
…tion
  • Loading branch information
Khoa Nguyen Dang authored and timhunt committed May 5, 2022
1 parent 7167471 commit b4f09ac
Show file tree
Hide file tree
Showing 12 changed files with 119 additions and 17 deletions.
3 changes: 3 additions & 0 deletions attempt.php
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
* @copyright 2017 HSR (http://www.hsr.ch)
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
use mod_studentquiz\utils;

require_once(__DIR__ . '/../../config.php');
require_once($CFG->libdir . '/questionlib.php');
Expand Down Expand Up @@ -199,6 +200,8 @@
$navinfo->total = $questionscount;
$PAGE->navbar->add(get_string('nav_question_no', 'studentquiz', $navinfo));

utils::require_access_to_a_relevant_group($cm, $context);

echo $OUTPUT->header();

$info = new stdClass();
Expand Down
23 changes: 22 additions & 1 deletion classes/utils.php
Original file line number Diff line number Diff line change
Expand Up @@ -479,7 +479,8 @@ public static function groups_get_questions_joins($groupid = 0, $groupidcolumn =
* @throws coding_exception if empty or invalid context submitted when $groupid = USERSWITHOUTGROUP
*/
public static function sq_groups_get_members_join($groupid, $useridcolumn, $context = null) {
if (!$groupid) {
// Don't need to join with group members if the user has the capability 'moodle/site:accessallgroups'.
if (!$groupid || has_capability('moodle/site:accessallgroups', $context)) {
$joins = '';
$wheres = '';
$params = [];
Expand Down Expand Up @@ -803,4 +804,24 @@ public static function get_question_names(array $questionids): array {

return $DB->get_records_list('question', 'id', $questionids, '', 'id, name');
}

/**
* Makes security checks for viewing. Will return an error message if the user cannot access the student quiz.
*
* @param object $cm - The course module object.
* @param \context $context The context module.
* @param string $title Page's title.
* @return void
*/
public static function require_access_to_a_relevant_group(object $cm, \context $context, string $title = ''): void {
global $COURSE, $PAGE;
$groupmode = (int)groups_get_activity_groupmode($cm, $COURSE);
$currentgroup = groups_get_activity_group($cm, true);

if ($groupmode === SEPARATEGROUPS && !$currentgroup && !has_capability('moodle/site:accessallgroups', $context)) {
$renderer = $PAGE->get_renderer('mod_studentquiz');
$renderer->render_error_message(get_string('error_permission', 'studentquiz'), $title);
exit();
}
}
}
3 changes: 3 additions & 0 deletions commenthistory.php
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
*/

use mod_studentquiz\commentarea\container;
use mod_studentquiz\utils;

require_once('../../config.php');
require_once($CFG->dirroot . '/mod/studentquiz/locallib.php');
Expand Down Expand Up @@ -76,6 +77,8 @@
$PAGE->set_heading($title);
$PAGE->set_url($actionurl);

utils::require_access_to_a_relevant_group($cm, $context);

echo $OUTPUT->header();
echo $renderer->render_comment_history($questionid, $commentid, $cmid);
echo $OUTPUT->footer();
3 changes: 3 additions & 0 deletions lang/en/studentquiz.php
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@
$string['approved_veryshort'] = 'A';
$string['approveselectedscheck'] = 'Are you sure you want to un-/approve the following questions?<br /><br />{$a}';
$string['average_column_name'] = 'Average';
$string['back_to_course_button'] = 'Back to course';
$string['before_answering_end_date'] = 'This StudentQuiz closes for answering on {$a}.';
$string['before_answering_start_date'] = 'Open for answering from {$a}.';
$string['before_submission_end_date'] = 'This StudentQuiz closes for question submission on {$a}.';
Expand Down Expand Up @@ -141,6 +142,7 @@
$string['error_form_validation'] = '{$a}';
$string['error_sendalert'] = 'There was an error sending your report to {$a}.
Report could not be sent.';
$string['error_permission'] = 'Sorry, but you need to be part of a group to see this page.';
$string['expandcomment'] = 'Expand comment';
$string['expandall'] = 'Expand all comments';
$string['filter'] = 'Filter';
Expand Down Expand Up @@ -572,6 +574,7 @@
$string['studentquiz:manage'] = 'Edit and delete questions on StudentQuiz';
$string['studentquiz:organize'] = 'Move questions into categories on StudentQuiz';
$string['studentquiz:pinquestion'] = 'Pin questions in StudentQuiz';
$string['studentquiz:preview'] = 'Preview questions';
$string['studentquiz:previewothers'] = 'Preview questions of others on StudentQuiz';
$string['studentquiz:submit'] = 'Create questions on StudentQuiz';
$string['studentquiz:systemnotifytaskdeleteorphanedquestions'] = 'Orphaned questions deleted notification';
Expand Down
11 changes: 7 additions & 4 deletions preview.php
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
* @copyright 2017 HSR (http://www.hsr.ch)
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
use mod_studentquiz\utils;

require_once(__DIR__ . '/../../config.php');
require_once(__DIR__ . '/viewlib.php');
Expand Down Expand Up @@ -51,6 +52,12 @@
\mod_studentquiz\access\context_override::ensure_permissions_are_right($context);

$studentquiz = mod_studentquiz_load_studentquiz($module->id, $context->id);
$output = $PAGE->get_renderer('mod_studentquiz', 'attempt');
$PAGE->set_pagelayout('popup');
$actionurl = new moodle_url('/mod/studentquiz/preview.php', array('cmid' => $cmid, 'questionid' => $questionid));
$PAGE->set_url($actionurl);

utils::require_access_to_a_relevant_group($module, $context, get_string('studentquiz:preview', 'studentquiz'));

// Lookup question.
try {
Expand All @@ -70,7 +77,6 @@
}

// Get and validate existing preview, or start a new one.
$actionurl = new moodle_url('/mod/studentquiz/preview.php', array('cmid' => $cmid, 'questionid' => $questionid));
$previewid = optional_param('previewid', 0, PARAM_INT);
$highlight = optional_param('highlight', 0, PARAM_INT);

Expand Down Expand Up @@ -129,11 +135,8 @@
} else {
$title = get_string('deletedquestion', 'qtype_missingtype');
}
$output = $PAGE->get_renderer('mod_studentquiz', 'attempt');
$PAGE->set_pagelayout('popup');
$PAGE->set_title($title);
$PAGE->set_heading($title);
$PAGE->set_url($actionurl);
$PAGE->requires->js_call_amd('mod_studentquiz/studentquiz', 'initialise');

echo $OUTPUT->header();
Expand Down
25 changes: 25 additions & 0 deletions renderer.php
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,31 @@ public function render_table_data(array $celldata, array $rowattributes=array())
return $rows;
}

/**
* Render custom error message, so we can write the behat test for it.
*
* @param string $errormessage Error message.
* @param string $title Page's title.
* @return void
*/
public function render_error_message(string $errormessage, string $title) : void {
if ($title) {
$this->page->set_title($title);
}
// We need to remove settings menu for view page because we are using custom error message.
if ($settingmenu = $this->page->settingsnav->find('modulesettings', \navigation_node::TYPE_SETTING)) {
$settingmenu->remove();
}
echo $this->output->header();
echo $this->output->notification($errormessage, 'error', false);
$courseurl = new moodle_url('/course/view.php', ['id' => $this->page->course->id]);

$backtocourse = new single_button($courseurl, get_string('back_to_course_button', 'studentquiz'),
'get', true);
echo html_writer::div($this->render($backtocourse), 'studentquizerrormessage');
echo $this->output->footer();
}

/**
* Render one table cell.
*
Expand Down
2 changes: 2 additions & 0 deletions reportcomment.php
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,8 @@
$PAGE->navbar->add($pagename);
}

utils::require_access_to_a_relevant_group($cm, $context);

// Keep referer url.
$action = (new moodle_url($PAGE->url, ['referer' => $referer]))->out(false);

Expand Down
10 changes: 7 additions & 3 deletions reportrank.php
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
* @copyright 2017 HSR (http://www.hsr.ch)
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
use mod_studentquiz\utils;

require_once(__DIR__ . '/../../config.php');
require_once(__DIR__ . '/reportlib.php');
Expand All @@ -31,14 +32,17 @@
}

$report = new mod_studentquiz_report($cmid);
require_login($report->get_course(), false, $report->get_coursemodule());
$cm = $report->get_coursemodule();
require_login($report->get_course(), false, $cm);
$context = $report->get_context();
$output = $PAGE->get_renderer('mod_studentquiz', 'ranking');

$PAGE->set_title($report->get_ranking_title());
$PAGE->set_heading($report->get_heading());
$PAGE->set_context($report->get_context());
$PAGE->set_url($report->get_rank_url());

$output = $PAGE->get_renderer('mod_studentquiz', 'ranking');
utils::require_access_to_a_relevant_group($cm, $context);

echo $OUTPUT->header();

Expand All @@ -47,4 +51,4 @@
echo $OUTPUT->footer();

// Trigger report rank viewed event.
mod_studentquiz_reportrank_viewed($report->get_cm_id(), $report->get_context());
mod_studentquiz_reportrank_viewed($report->get_cm_id(), $context);
10 changes: 6 additions & 4 deletions reportstat.php
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
* @copyright 2017 HSR (http://www.hsr.ch)
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
use mod_studentquiz\utils;

require_once(__DIR__ . '/../../config.php');
require_once(__DIR__ . '/reportlib.php');
Expand All @@ -31,19 +32,20 @@
}

$report = new mod_studentquiz_report($cmid);
$cm = $report->get_coursemodule();

require_login($report->get_course(), false, $report->get_coursemodule());

require_login($report->get_course(), false, $cm);
$context = context_module::instance($cmid);
$renderer = $PAGE->get_renderer('mod_studentquiz', 'report');

$PAGE->set_title($report->get_statistic_title());
$PAGE->set_heading($report->get_heading());
$PAGE->set_context($report->get_context());
$PAGE->set_url($report->get_stat_url());

echo $OUTPUT->header();
utils::require_access_to_a_relevant_group($cm, $context);

$renderer = $PAGE->get_renderer('mod_studentquiz', 'report');
echo $OUTPUT->header();

echo $renderer->view_stat($report);

Expand Down
3 changes: 2 additions & 1 deletion styles.css
Original file line number Diff line number Diff line change
Expand Up @@ -819,7 +819,8 @@
}

.path-mod-studentquiz #categoryquestions .header.qtype,
.path-mod-studentquiz #categoryquestions .header.state {
.path-mod-studentquiz #categoryquestions .header.state,
.path-mod-studentquiz .studentquizerrormessage {
text-align: center;
}

Expand Down
40 changes: 36 additions & 4 deletions tests/behat/group_separate_groups.feature
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,19 @@ Feature: Students can create questions and practice in separate groups.
| student1 | Student | One | student1@example.com |
| student2 | Student | Two | student2@example.com |
| student3 | Student | Three | student3@example.com |
| student4 | Student | Four | student4@example.com |
| teacher | Teacher | One | teacher@example.com |
And the following "courses" exist:
| fullname | shortname | category |
| Course 1 | C1 | 0 |

And the following "course enrolments" exist:
| user | course | role |
| student1 | C1 | student |
| student2 | C1 | student |
| student3 | C1 | student |
| user | course | role |
| student1 | C1 | student |
| student2 | C1 | student |
| student3 | C1 | student |
| student4 | C1 | student |
| teacher | C1 | editingteacher |
And the following "groups" exist:
| name | course | idnumber |
| Group 1 | C1 | G1 |
Expand Down Expand Up @@ -123,3 +127,31 @@ Feature: Students can create questions and practice in separate groups.
And I should see "Separate groups: Group 1"
And "Student One" "text" should appear before "Student Two" "text"
And I should not see "Student Three"

@javascript
Scenario: Students without a group will not be able to access the Student Quiz activity in separate groups.
Given I am on the "C1" "Course" page logged in as "student4"
And I follow "StudentQuiz 1"
Then I should see "Sorry, but you need to be part of a group to see this page."
And "Back to course" "button" should exist

@javascript
Scenario: Teacher without a group but has the capability 'moodle/site:accessallgroups' can write a comment on Student Quiz in separate groups.
Given I am on the "C1" "Course" page logged in as "admin"
And I follow "StudentQuiz 1"
And I click on "Create new question" "button"
And I set the field "item_qtype_truefalse" to "1"
And I click on "Add" "button" in the "Choose a question type to add" "dialogue"
And I set the field "Question name" to "Question of Student 1"
And I set the field "Question text" to "The correct answer is true"
And I press "id_submitbutton"
And I log out
And I am on the "C1" "Course" page logged in as "teacher"
And I follow "StudentQuiz 1"
And I click on "Start Quiz" "button"
And I set the field "True" to "1"
And I press "Check"
And I enter the text "Comment 1" into the "Add public comment" editor
And I press "Add comment"
And I wait until ".studentquiz-comment-item:nth-child(1)" "css_element" exists
Then I should see "Comment 1" in the ".studentquiz-comment-item:nth-child(1) .studentquiz-comment-text" "css_element"
3 changes: 3 additions & 0 deletions view.php
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
* @copyright 2017 HSR (http://www.hsr.ch)
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
use mod_studentquiz\utils;

require_once(__DIR__ . '/../../config.php');
require_once(__DIR__ . '/viewlib.php');
Expand Down Expand Up @@ -100,6 +101,8 @@
$PAGE->set_heading($COURSE->fullname);
$PAGE->set_cm($cm, $course);

utils::require_access_to_a_relevant_group($cm, $context);

// Process actions.
$view->process_actions();

Expand Down

0 comments on commit b4f09ac

Please sign in to comment.