Skip to content

Commit

Permalink
MDL-76665 quizaccess_seb: Allow disable of SEB templates when in use.
Browse files Browse the repository at this point in the history
  • Loading branch information
Michael Kotlyar committed Sep 4, 2024
1 parent 13c1275 commit 1422816
Show file tree
Hide file tree
Showing 6 changed files with 170 additions and 14 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@
*/

use quizaccess_seb\seb_quiz_settings;
use quizaccess_seb\settings_provider;
use quizaccess_seb\template;

defined('MOODLE_INTERNAL') || die();

Expand Down Expand Up @@ -73,7 +75,15 @@ public function process_quizaccess_seb_quizsettings($data) {
unset($data->id);
$data->timecreated = $data->timemodified = time();
$data->usermodified = $USER->id;
$DB->insert_record(quizaccess_seb\seb_quiz_settings::TABLE, $data);

// Do not use template if it is no longer enabled.
if ($data->requiresafeexambrowser == settings_provider::USE_SEB_TEMPLATE &&
!$DB->record_exists(template::TABLE, ['id' => $data->templateid, 'enabled' => '1'])) {
$data->templateid = 0;
$data->requiresafeexambrowser = settings_provider::USE_SEB_NO;
}

$DB->insert_record(seb_quiz_settings::TABLE, $data);

// Process attached files.
$this->add_related_files('quizaccess_seb', 'filemanager_sebconfigfile', null);
Expand Down Expand Up @@ -112,7 +122,10 @@ public function process_quizaccess_seb_template($data) {
}

// Update the restored quiz settings to use restored template.
$DB->set_field(\quizaccess_seb\seb_quiz_settings::TABLE, 'templateid', $template->get('id'), ['quizid' => $quizid]);
// Check if template is enabled before using it.
if ($template->get('enabled')) {
$DB->set_field(seb_quiz_settings::TABLE, 'templateid', $template->get('id'), ['quizid' => $quizid]);
}
}

}
Expand Down
9 changes: 4 additions & 5 deletions mod/quiz/accessrule/seb/classes/local/form/template.php
Original file line number Diff line number Diff line change
Expand Up @@ -62,12 +62,11 @@ protected function definition() {
$mform->addElement('selectyesno', 'enabled', get_string('enabled', 'quizaccess_seb'));
$mform->setType('enabled', PARAM_INT);

$this->add_action_buttons();

if (!empty($this->get_persistent()) && !$this->get_persistent()->can_delete()) {
$mform->hardFreezeAllVisibleExcept([]);
$mform->addElement('cancel');
if ($this->get_persistent()->get('id')) {
$mform->hardFreezeAllVisibleExcept(['enabled']);
}

$this->add_action_buttons();
}

/**
Expand Down
23 changes: 16 additions & 7 deletions mod/quiz/accessrule/seb/classes/settings_provider.php
Original file line number Diff line number Diff line change
Expand Up @@ -212,12 +212,13 @@ protected static function add_seb_usage_options(\mod_quiz_mod_form $quizform, \M
* @param \MoodleQuickForm $mform the wrapped MoodleQuickForm.
*/
protected static function add_seb_templates(\mod_quiz_mod_form $quizform, \MoodleQuickForm $mform) {
if (self::can_use_seb_template($quizform->get_context()) || self::is_conflicting_permissions($quizform->get_context())) {
$context = $quizform->get_context();
if (self::can_use_seb_template($context) || self::is_conflicting_permissions($context)) {
$element = $mform->createElement(
'select',
'seb_templateid',
get_string('seb_templateid', 'quizaccess_seb'),
self::get_template_options()
self::get_template_options($context->instanceid)
);
} else {
$element = $mform->createElement('hidden', 'seb_templateid');
Expand All @@ -230,7 +231,7 @@ protected static function add_seb_templates(\mod_quiz_mod_form $quizform, \Moodl

// In case if the user can't use templates, but the quiz is configured to use them,
// we'd like to display template, but freeze it.
if (self::is_conflicting_permissions($quizform->get_context())) {
if (self::is_conflicting_permissions($context)) {
self::freeze_element($quizform, $mform, 'seb_templateid');
}
}
Expand Down Expand Up @@ -566,7 +567,7 @@ public static function get_requiresafeexambrowser_options(\context $context): ar
}

if (self::can_use_seb_template($context) || self::is_conflicting_permissions($context)) {
if (!empty(self::get_template_options())) {
if (!empty(self::get_template_options($context->instanceid))) {
$options[self::USE_SEB_TEMPLATE] = get_string('seb_use_template', 'quizaccess_seb');
}
}
Expand All @@ -584,10 +585,18 @@ public static function get_requiresafeexambrowser_options(\context $context): ar
* Returns a list of templates.
* @return array
*/
protected static function get_template_options(): array {
protected static function get_template_options($cmid): array {
$templates = [];
$records = template::get_records(['enabled' => 1], 'name');
if ($records) {
$templatetable = template::TABLE;
$sebquizsettingstable = seb_quiz_settings::TABLE;
$select = "enabled = 1
OR EXISTS (
SELECT 1
FROM {{$sebquizsettingstable}}
WHERE templateid = {{$templatetable}}.id
AND cmid = ?
)";
if ($records = template::get_records_select($select, [$cmid], 'id, name')) {
foreach ($records as $record) {
$templates[$record->get('id')] = $record->get('name');
}
Expand Down
42 changes: 42 additions & 0 deletions mod/quiz/accessrule/seb/tests/backup_restore_test.php
Original file line number Diff line number Diff line change
Expand Up @@ -193,6 +193,48 @@ public function test_backup_restore_template_config(): void {
$this->validate_backup_restore($newcm);
}

/**
* Test backup and restore when using template when said template is disabled.
*
* @covers \quizaccess_seb\seb_quiz_settings::get_record
* @covers \restore_quizaccess_seb_subplugin::process_quizaccess_seb_quizsettings
*/
public function test_backup_restore_disabled_template_config(): void {
$this->quiz = $this->create_test_quiz($this->course, settings_provider::USE_SEB_CONFIG_MANUALLY);

$expected = seb_quiz_settings::get_record(['quizid' => $this->quiz->id]);
$template = $this->create_template();
$expected->set('requiresafeexambrowser', settings_provider::USE_SEB_TEMPLATE);
$expected->set('templateid', $template->get('id'));
$expected->save();

// Disable template.
$template->set('enabled', 0);
$template->save();

$this->assertEquals(1, seb_quiz_settings::count_records());

$newcm = $this->backup_and_restore_quiz();

$this->assertEquals(2, seb_quiz_settings::count_records());
$actual = seb_quiz_settings::get_record(['quizid' => $newcm->instance]);

// Test that the restored quiz no longer uses SEB.
$expected = seb_quiz_settings::get_record(['quizid' => $this->quiz->id]);
$this->assertEquals(0, $actual->get('templateid'));
$this->assertEquals(settings_provider::USE_SEB_NO, $actual->get('requiresafeexambrowser'));
$this->assertEquals($expected->get('showsebdownloadlink'), $actual->get('showsebdownloadlink'));
$this->assertEquals($expected->get('allowuserquitseb'), $actual->get('allowuserquitseb'));
$this->assertEquals($expected->get('quitpassword'), $actual->get('quitpassword'));
$this->assertEquals($expected->get('allowedbrowserexamkeys'), $actual->get('allowedbrowserexamkeys'));

// Validate specific SEB config settings.
foreach (settings_provider::get_seb_config_elements() as $name => $notused) {
$name = preg_replace("/^seb_/", "", $name);
$this->assertEquals($expected->get($name), $actual->get($name));
}
}

/**
* Test backup and restore when using uploaded file.
*/
Expand Down
32 changes: 32 additions & 0 deletions mod/quiz/accessrule/seb/tests/behat/edit_form.feature
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ Feature: Safe Exam Browser settings in quiz edit form
And the following "activities" exist:
| activity | course | section | name |
| quiz | C1 | 1 | Quiz 1 |
| quiz | C1 | 1 | Quiz 2 |

Scenario: Quiz setting "Require the use of Safe Exam Browser" has all types, except "Use an existing template".
When I am on the "Quiz 1" "quiz activity editing" page logged in as admin
Expand Down Expand Up @@ -232,3 +233,34 @@ Feature: Safe Exam Browser settings in quiz edit form
Then I should not see "Allowed browser exam keys"
Then I should not see "Safe Exam Browser config template"
Then I should not see "Template 1"

Scenario: Disable templates that are already in use and seeing their visibility in settings
Given the following "quizaccess_seb > seb templates" exist:
| name | enabled |
| Template 1 | 1 |
| Template 2 | 0 |
# Set Quiz 1 template to Template 1
When I am on the "Quiz 1" "quiz activity editing" page logged in as admin
And I expand all fieldsets
And I set the field "Require the use of Safe Exam Browser" to "Yes – Use an existing template"
Then I should see "Safe Exam Browser config template"
And the "Safe Exam Browser config template" select box should contain "Template 1"
And the "Safe Exam Browser config template" select box should not contain "Template 2"
And I set the field "Safe Exam Browser config template" to "Template 1"
And I press "Save and return to course"
# Disable Template 1
And I navigate to "Plugins > Activity modules > Category: Quiz > Safe Exam Browser templates" in site administration
And I click on "Edit" "link" in the "Template 1" "table_row"
And I set the field "Enabled" to "No"
And I press "Save changes"
# Check Quiz 1 is still using Template 1
When I am on the "Quiz 1" "quiz activity editing" page logged in as admin
And I expand all fieldsets
And the field "Require the use of Safe Exam Browser" matches value "Yes – Use an existing template"
Then I should see "Template 1"
And the "Safe Exam Browser config template" select box should contain "Template 1"
And the "Safe Exam Browser config template" select box should not contain "Template 2"
# Check Quiz 3 cannot use any templates as they're all disabled
When I am on the "Quiz 2" "quiz activity editing" page logged in as admin
And I expand all fieldsets
And the "Require the use of Safe Exam Browser" select box should not contain "Yes – Use an existing template"
61 changes: 61 additions & 0 deletions mod/quiz/accessrule/seb/tests/template_test.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,10 @@

namespace quizaccess_seb;

defined('MOODLE_INTERNAL') || die();

require_once(__DIR__ . '/test_helper_trait.php');

/**
* PHPUnit tests for template class.
*
Expand All @@ -25,6 +29,7 @@
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class template_test extends \advanced_testcase {
use \quizaccess_seb_test_helper_trait;

/**
* Called before every test.
Expand Down Expand Up @@ -140,4 +145,60 @@ public function test_cannot_delete_template_when_assigned_to_quiz(): void {
$this->assertFalse($template->can_delete());
}

/**
* Test that a disabled template no longer shows up in quiz SEB settings other than quizzes already using it.
*
* @covers \quizaccess_seb\seb_quiz_settings::get_record
* @covers \quizaccess_seb\settings_provider::get_requiresafeexambrowser_options
*/
public function test_disabled_template_quiz_setting_options(): void {
// Create quiz and fetch standard SEB requirement options.
$this->setAdminUser();
$this->course = $this->getDataGenerator()->create_course();

$templateoptionstr = get_string('seb_use_template', 'quizaccess_seb');

// Create a quiz.
$this->quiz = $this->create_test_quiz($this->course, settings_provider::USE_SEB_CONFIG_MANUALLY);
$context = \context_module::instance($this->quiz->cmid);

// Check there is no template option (as there aren't any).
$options = settings_provider::get_requiresafeexambrowser_options($context);
$this->assertNotContainsEquals($templateoptionstr, $options);

// Create a template.
$data = new \stdClass();
$data->name = 'Test name';
$data->description = 'Test description';
$data->enabled = 1;
$data->content = file_get_contents(__DIR__ . '/fixtures/unencrypted.seb');
$template = new template(0, $data);
$template->save();

// Check options now include template option.
$options = settings_provider::get_requiresafeexambrowser_options($context);
$this->assertContainsEquals($templateoptionstr, $options);

// Set SEB setting to use template for quiz.
$settings = seb_quiz_settings::get_record(['quizid' => $this->quiz->id]);
$settings->set('templateid', $template->get('id'));
$settings->set('requiresafeexambrowser', settings_provider::USE_SEB_TEMPLATE);
$settings->save();

// Disable template.
$template->set('enabled', 0);
$template->save();

// Check option still exists on current quiz.
$options = settings_provider::get_requiresafeexambrowser_options($context);
$this->assertContainsEquals($templateoptionstr, $options);

// Create a new quiz.
$newquiz = $this->create_test_quiz($this->course, settings_provider::USE_SEB_CONFIG_MANUALLY);
$context = \context_module::instance($newquiz->cmid);

// Check there is no template option (as the template is now disabled).
$options = settings_provider::get_requiresafeexambrowser_options($context);
$this->assertNotContainsEquals($templateoptionstr, $options);
}
}

0 comments on commit 1422816

Please sign in to comment.