first commit

This commit is contained in:
CHIEFSOFT\ameye
2024-09-30 18:11:26 -04:00
commit e592ca6823
27270 changed files with 5002257 additions and 0 deletions
@@ -0,0 +1,60 @@
@core @core_question @core_customfield @qbank_customfields @javascript
Feature: A teacher can edit question with custom fields
In order to improve my questions
As a teacher
I need to be able to edit questions and add extra metadata via custom fields
Background:
Given the following "users" exist:
| username | firstname | lastname | email |
| teacher1 | Teacher | 1 | teacher1@example.com |
And the following "courses" exist:
| fullname | shortname | format |
| Course 1 | C1 | weeks |
And the following "course enrolments" exist:
| user | course | role |
| teacher1 | C1 | editingteacher |
And the following "custom field categories" exist:
| name | component | area | itemid |
| Category for test | qbank_customfields | question | 0 |
And the following "custom fields" exist:
| name | category | type | shortname |
| Field 1 | Category for test | text | f1 |
And the following "activity" exists:
| activity | quiz |
| course | C1 |
| idnumber | 00001 |
| name | Test quiz name |
| intro | Test quiz description |
| section | 1 |
| grade | 10 |
And I log in as "teacher1"
And I am on "Course 1" course homepage with editing mode on
And I add a "True/False" question to the "Test quiz name" quiz with:
| Question name | First question |
| Question text | Answer the first question |
| General feedback | Thank you, this is the general feedback |
| Correct answer | False |
| Feedback for the response 'True'. | So you think it is true |
| Feedback for the response 'False'. | So you think it is false |
And I am on the "Test quiz name" "mod_quiz > question bank" page
Scenario: Edit a previously created question and see the custom field in the overview table and in the question preview.
When I am on the "First question" "core_question > edit" page
Then I should see "Category for test"
And I expand all fieldsets
And I should see "Field 1"
And I set the following fields to these values:
| Question name | First question edited |
| Field 1 | custom field text |
And I press "id_submitbutton"
And I should see "First question"
And I should see "custom field text"
And I am on the "First question edited" "core_question > preview" page
And I should see "Field 1"
And I should see "custom field text"
Scenario: Preview a previously created question with custom fields set with empty values
When I am on the "First question" "core_question > preview" page
Then I should see "Field 1"
And I should not see "custom field text"
@@ -0,0 +1,98 @@
@core @core_question @core_customfield @qbank_customfields @javascript
Feature: Site administrators can manage categories for question custom fields
In order to have additional data in questions
As a site site administrator
I need to create, edit, remove and sort question custom field categories
Scenario: Create a category for custom question fields
Given I log in as "admin"
When I navigate to "Plugins > Question bank plugins > Question custom fields" in site administration
And I press "Add a new category"
And I wait until the page is ready
Then I should see "Other fields" in the "#customfield_catlist" "css_element"
Scenario: Edit a category name for custom question fields
Given the following "custom field categories" exist:
| name | component | area | itemid |
| Category for test | qbank_customfields | question | 0 |
And I log in as "admin"
And I navigate to "Plugins > Question bank plugins > Question custom fields" in site administration
And I set the field "Edit category name" in the "//div[contains(@class,'categoryinstance') and contains(.,'Category for test')]" "xpath_element" to "Good fields"
Then I should not see "Category for test" in the "#customfield_catlist" "css_element"
And "New value for Category for test" "field" should not exist
And I should see "Good fields" in the "#customfield_catlist" "css_element"
Scenario: Delete a category for custom question fields
Given the following "custom field categories" exist:
| name | component | area | itemid |
| Category for test | qbank_customfields | question | 0 |
And the following "custom fields" exist:
| name | category | type | shortname |
| Field 1 | Category for test | text | f1 |
And I log in as "admin"
And I navigate to "Plugins > Question bank plugins > Question custom fields" in site administration
And I click on "[data-role='deletecategory']" "css_element"
And I click on "Yes" "button" in the "Confirm" "dialogue"
And I wait until the page is ready
And I wait until "Test category" "text" does not exist
Then I should not see "Test category" in the "#customfield_catlist" "css_element"
Scenario: Move field in the question custom fields to another category
Given the following "custom field categories" exist:
| name | component | area | itemid |
| Category1 | qbank_customfields | question | 0 |
| Category2 | qbank_customfields | question | 0 |
| Category3 | qbank_customfields | question | 0 |
And the following "custom fields" exist:
| name | category | type | shortname |
| Field1 | Category1 | text | f1 |
| Field2 | Category2 | text | f2 |
When I log in as "admin"
And I navigate to "Plugins > Question bank plugins > Question custom fields" in site administration
Then "Field1" "text" should appear after "Category1" "text"
And "Category2" "text" should appear after "Field1" "text"
And "Field2" "text" should appear after "Category2" "text"
And "Category3" "text" should appear after "Field2" "text"
And I press "Move \"Field1\""
And I follow "To the top of category Category2"
And "Category2" "text" should appear after "Category1" "text"
And "Field1" "text" should appear after "Category2" "text"
And "Field2" "text" should appear after "Field1" "text"
And "Category3" "text" should appear after "Field2" "text"
And I navigate to "Plugins > Question bank plugins > Question custom fields" in site administration
And "Category2" "text" should appear after "Category1" "text"
And "Field1" "text" should appear after "Category2" "text"
And "Field2" "text" should appear after "Field1" "text"
And "Category3" "text" should appear after "Field2" "text"
And I press "Move \"Field1\""
And I follow "After field Field2"
And "Field1" "text" should appear after "Field2" "text"
Scenario: Reorder question custom field categories
Given the following "custom field categories" exist:
| name | component | area | itemid |
| Category1 | qbank_customfields | question | 0 |
| Category2 | qbank_customfields | question | 0 |
| Category3 | qbank_customfields | question | 0 |
And the following "custom fields" exist:
| name | category | type | shortname |
| Field1 | Category1 | text | f1 |
When I log in as "admin"
And I navigate to "Plugins > Question bank plugins > Question custom fields" in site administration
Then "Field1" "text" should appear after "Category1" "text"
And "Category2" "text" should appear after "Field1" "text"
And "Category3" "text" should appear after "Category2" "text"
And I press "Move \"Category2\""
And I follow "After \"Category3\""
And "Field1" "text" should appear after "Category1" "text"
And "Category3" "text" should appear after "Field1" "text"
And "Category2" "text" should appear after "Category3" "text"
And I navigate to "Plugins > Question bank plugins > Question custom fields" in site administration
And "Field1" "text" should appear after "Category1" "text"
And "Category3" "text" should appear after "Field1" "text"
And "Category2" "text" should appear after "Category3" "text"
And I press "Move \"Category2\""
And I follow "After \"Category1\""
And "Field1" "text" should appear after "Category1" "text"
And "Category2" "text" should appear after "Field1" "text"
And "Category3" "text" should appear after "Category2" "text"
@@ -0,0 +1,65 @@
@core @core_quiz @core_customfield @qbank_customfields @javascript
Feature: The visibility of question custom fields control where they are displayed
In order to display custom fields in a quiz
Background:
Given the following "users" exist:
| username | firstname | lastname | email |
| teacher1 | Terry1 | Teacher1 | teacher1@example.com |
And the following "courses" exist:
| fullname | shortname | format |
| Course 1 | C1 | weeks |
And the following "course enrolments" exist:
| user | course | role |
| teacher1 | C1 | editingteacher |
And the following "custom field categories" exist:
| name | component | area | itemid |
| Category for test | qbank_customfields | question | 0 |
And the following "custom fields" exist:
| name | category | type | shortname | configdata |
| Field 1 | Category for test | text | f1 | {"visibility":"2"} |
| Field 2 | Category for test | text | f2 | {"visibility":"2"} |
| Field 3 | Category for test | text | f3 | {"visibility":"2","defaultvalue":"secret"} |
And the following "activity" exists:
| activity | quiz |
| course | C1 |
| idnumber | 00001 |
| name | Test quiz name |
| intro | Test quiz description |
| section | 1 |
| grade | 10 |
When I log in as "teacher1"
And I am on "Course 1" course homepage with editing mode on
And I add a "True/False" question to the "Test quiz name" quiz with:
| Question name | First question |
| Question text | Answer the first question |
| General feedback | Thank you, this is the general feedback |
| Correct answer | False |
| Feedback for the response 'True'. | So you think it is true |
| Feedback for the response 'False'. | So you think it is false |
@javascript
Scenario: Display custom question fields to teachers based on their visibility.
When I am on the "First question" "core_question > edit" page
Then I should see "Category for test"
And I expand all fieldsets
And I should see "Field 1"
And I should see "Field 2"
And I should see "Field 3"
And I set the following fields to these values:
| Field 1 | custom field text one|
| Field 2 | custom field text two|
And I press "id_submitbutton"
And I should see "Field 1"
And I should see "custom field text one"
And I should see "Field 2"
And I should see "custom field text two"
And I should see "Field 3"
And I should see "secret"
And I choose "Preview" action for "First question" in the question bank
And I should see "Field 1"
And I should see "custom field text one"
And I should see "Field 2"
And I should see "custom field text two"
And I should see "Field 3"
And I should see "secret"
@@ -0,0 +1,313 @@
<?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 qbank_customfields;
defined('MOODLE_INTERNAL') || die();
global $CFG;
require_once($CFG->dirroot . '/backup/util/includes/backup_includes.php');
require_once($CFG->dirroot . '/backup/util/includes/restore_includes.php');
/**
* Class qbank_customfields_customfield_testcase
*
* @package qbank_customfields
* @copyright 2021 Catalyst IT Australia Pty Ltd
* @author Matt Porritt <mattp@catalyst-au.net>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class customfield_test extends \advanced_testcase {
/**
* @var array Data object for generating a question.
*/
protected $question1data;
/**
* @var array Data object for generating a question.
*/
protected $question2data;
/**
* @var component_generator_base Question Generator.
*/
protected $qgen;
/**
* @var core_course_category Course category.
*/
protected $category;
/**
* @var stdClass Course object.
*/
protected $course;
/**
* @var int Timestamp to use in tests.
*/
protected $testnow = 1632278491;
/**
* Helper to assist with setting up custom fields.
* This is creating custom field category and the fields, not adding instance field data.
*/
protected function setup_custom_fields(): void {
$dg = self::getDataGenerator();
$data = new \stdClass();
$data->component = 'qbank_customfields';
$data->area = 'question';
$catid = $dg->create_custom_field_category($data)->get('id');
$dg->create_custom_field(['categoryid' => $catid, 'type' => 'text', 'shortname' => 'f1']);
$dg->create_custom_field(['categoryid' => $catid, 'type' => 'checkbox', 'shortname' => 'f2']);
$dg->create_custom_field(['categoryid' => $catid, 'type' => 'date', 'shortname' => 'f3',
'configdata' => ['startyear' => 2000, 'endyear' => 3000, 'includetime' => 1]]);
$dg->create_custom_field(['categoryid' => $catid, 'type' => 'select', 'shortname' => 'f4',
'configdata' => ['options' => "a\nb\nc"]]);
$dg->create_custom_field(['categoryid' => $catid, 'type' => 'textarea', 'shortname' => 'f5']);
}
/**
* Helper to assist with setting up questions used in tests.
*/
protected function setup_questions(): void {
// Question initial set up.
$this->category = $this->getDataGenerator()->create_category();
$this->course = $this->getDataGenerator()->create_course(['category' => $this->category->id]);
$context = \context_coursecat::instance($this->category->id);
$this->qgen = $this->getDataGenerator()->get_plugin_generator('core_question');
$qcat = $this->qgen->create_question_category(['contextid' => $context->id]);
$this->question1data = [
'category' => $qcat->id, 'idnumber' => 'q1',
'customfield_f1' => 'some text', 'customfield_f2' => 1,
'customfield_f3' => $this->testnow, 'customfield_f4' => 2,
'customfield_f5_editor' => ['text' => 'test', 'format' => FORMAT_HTML]];
$this->question2data = [
'category' => $qcat->id, 'idnumber' => 'q2',
'customfield_f1' => 'some more text', 'customfield_f2' => 0,
'customfield_f3' => $this->testnow, 'customfield_f4' => 1,
'customfield_f5_editor' => ['text' => 'test text', 'format' => FORMAT_HTML]];
}
/**
* Makes a backup of the course.
*
* @param \stdClass $course The course object.
* @return string Unique identifier for this backup.
*/
protected function backup_course(\stdClass $course): string {
global $CFG, $USER;
// Turn off file logging, otherwise it can't delete the file (Windows).
$CFG->backup_file_logger_level = \backup::LOG_NONE;
// Do backup with default settings. MODE_IMPORT means it will just
// create the directory and not zip it.
$bc = new \backup_controller(\backup::TYPE_1COURSE, $course->id,
\backup::FORMAT_MOODLE, \backup::INTERACTIVE_NO, \backup::MODE_IMPORT,
$USER->id);
$backupid = $bc->get_backupid();
$bc->execute_plan();
$bc->destroy();
return $backupid;
}
/**
* Restores a backup that has been made earlier.
*
* @param string $backupid The unique identifier of the backup.
* @param string $fullname Full name of the new course that is going to be created.
* @param string $shortname Short name of the new course that is going to be created.
* @param int $categoryid The course category the backup is going to be restored in.
* @return int The new course id.
*/
protected function restore_course(string $backupid, string $fullname, string $shortname, int $categoryid): int {
global $CFG, $USER;
// Turn off file logging, otherwise it can't delete the file (Windows).
$CFG->backup_file_logger_level = \backup::LOG_NONE;
// Do restore to new course with default settings.
$newcourseid = \restore_dbops::create_new_course($fullname, $shortname, $categoryid);
$rc = new \restore_controller($backupid, $newcourseid,
\backup::INTERACTIVE_NO, \backup::MODE_GENERAL, $USER->id,
\backup::TARGET_NEW_COURSE);
$rc->execute_precheck();
$rc->execute_plan();
$rc->destroy();
return $newcourseid;
}
/**
* Test creating questions with custom fields.
*/
public function test_create_question(): void {
$this->resetAfterTest();
$this->setAdminUser();
$this->setup_custom_fields();
$this->setup_questions();
// Create 2 questions.
$question1 = $this->qgen->create_question('shortanswer', null, $this->question1data);
$question2 = $this->qgen->create_question('shortanswer', null, $this->question2data);
// Explicitly save the custom field data for the questions, like a form would.
$customfieldhandler = \qbank_customfields\customfield\question_handler::create();
$this->question1data['id'] = $question1->id;
$this->question2data['id'] = $question2->id;
$customfieldhandler->instance_form_save((object)$this->question1data);
$customfieldhandler->instance_form_save((object)$this->question2data);
// Get the custom field data associated with these question ids.
$q1cfdata = $customfieldhandler->export_instance_data_object($question1->id);
$q2cfdata = $customfieldhandler->export_instance_data_object($question2->id);
$this->assertEquals('some text', $q1cfdata->f1);
$this->assertEquals('Yes', $q1cfdata->f2);
$this->assertEquals(userdate($this->testnow, get_string('strftimedaydatetime')), $q1cfdata->f3);
$this->assertEquals('b', $q1cfdata->f4);
$this->assertEquals('test', $q1cfdata->f5);
$this->assertEquals('some more text', $q2cfdata->f1);
$this->assertEquals('No', $q2cfdata->f2);
$this->assertEquals(userdate($this->testnow, get_string('strftimedaydatetime')), $q2cfdata->f3);
$this->assertEquals('a', $q2cfdata->f4);
$this->assertEquals('test text', $q2cfdata->f5);
}
/**
* Test deleting questions with custom fields.
*/
public function test_delete_question(): void {
$this->resetAfterTest();
$this->setAdminUser();
$this->setup_custom_fields();
$this->setup_questions();
// Create 2 questions.
$question1 = $this->qgen->create_question('shortanswer', null, $this->question1data);
$question2 = $this->qgen->create_question('shortanswer', null, $this->question2data);
// Explicitly save the custom field data for the questions, like a form would.
$customfieldhandler = \qbank_customfields\customfield\question_handler::create();
$this->question1data['id'] = $question1->id;
$this->question2data['id'] = $question2->id;
$customfieldhandler->instance_form_save((object)$this->question1data);
$customfieldhandler->instance_form_save((object)$this->question2data);
// Get the custom field data associated with these question ids.
$q1cfdata = $customfieldhandler->export_instance_data_object($question1->id);
$q2cfdata = $customfieldhandler->export_instance_data_object($question2->id);
// Quick check that we have data for the custom fields.
$this->assertEquals('some text', $q1cfdata->f1);
$this->assertEquals('some more text', $q2cfdata->f1);
// Delete the questions.
question_delete_question($question1->id);
question_delete_question($question2->id);
// Check the custom field data for the questions has also gone.
$q1cfdata = $customfieldhandler->export_instance_data_object($question1->id);
$q2cfdata = $customfieldhandler->export_instance_data_object($question2->id);
$this->assertEmpty($q1cfdata->f1);
$this->assertEmpty($q2cfdata->f1);
}
/**
* Test custom fields attached to questions persist
* across the backup and restore process.
*/
public function test_backup_restore(): void {
global $DB;
$this->resetAfterTest();
$this->setAdminUser();
$this->setup_custom_fields();
$this->setup_questions();
$courseshortname = $this->course->shortname;
$coursefullname = $this->course->fullname;
// Create 2 questions.
$question1 = $this->qgen->create_question('shortanswer', null, $this->question1data);
$question2 = $this->qgen->create_question('shortanswer', null, $this->question2data);
// Explicitly save the custom field data for the questions, like a form would.
$customfieldhandler = \qbank_customfields\customfield\question_handler::create();
$this->question1data['id'] = $question1->id;
$this->question2data['id'] = $question2->id;
$customfieldhandler->instance_form_save((object)$this->question1data);
$customfieldhandler->instance_form_save((object)$this->question2data);
// Create a quiz and the questions to that.
$quiz = $this->getDataGenerator()->create_module(
'quiz', ['course' => $this->course->id, 'name' => 'restored_quiz']);
quiz_add_quiz_question($question1->id, $quiz);
quiz_add_quiz_question($question2->id, $quiz);
// Backup the course.
$backupid = $this->backup_course($this->course);
// Now delete everything.
delete_course($this->course, false);
question_delete_question($question1->id);
question_delete_question($question2->id);
// Check the custom field data for the questions has also gone.
$q1cfdata = $customfieldhandler->export_instance_data_object($question1->id);
$q2cfdata = $customfieldhandler->export_instance_data_object($question2->id);
$this->assertEmpty($q1cfdata->f1);
$this->assertEmpty($q2cfdata->f1);
// Restore the backup we had made earlier into a new course.
$newcategory = $this->getDataGenerator()->create_category();
$this->restore_course($backupid, $coursefullname, $courseshortname . '_2', $newcategory->id);
// The questions and their associated custom fields should have been restored.
$sql = 'SELECT q.*
FROM {question} q
JOIN {question_versions} qv ON qv.questionid = q.id
JOIN {question_bank_entries} qbe ON qbe.id = qv.questionbankentryid
WHERE qbe.idnumber = ?';
$newquestion1 = $DB->get_record_sql($sql, ['q1']);
$newquestion1cfdata = $customfieldhandler->export_instance_data_object($newquestion1->id);
$this->assertEquals('some text', $newquestion1cfdata->f1);
$this->assertEquals('Yes', $newquestion1cfdata->f2);
$this->assertEquals(userdate($this->testnow, get_string('strftimedaydatetime')), $newquestion1cfdata->f3);
$this->assertEquals('b', $newquestion1cfdata->f4);
$this->assertEquals('test', $newquestion1cfdata->f5);
$newquestion2 = $DB->get_record_sql($sql, ['q2']);
$newquestion2cfdata = $customfieldhandler->export_instance_data_object($newquestion2->id);
$this->assertEquals('some more text', $newquestion2cfdata->f1);
$this->assertEquals('No', $newquestion2cfdata->f2);
$this->assertEquals(userdate($this->testnow, get_string('strftimedaydatetime')), $newquestion2cfdata->f3);
$this->assertEquals('a', $newquestion2cfdata->f4);
$this->assertEquals('test text', $newquestion2cfdata->f5);
}
}
@@ -0,0 +1,68 @@
<?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 qbank_customfields\event;
/**
* Tests for question_deleted_observer
*
* @package qbank_customfields
* @copyright 2023 onwards Catalyst IT EU {@link https://catalyst-eu.net}
* @author Mark Johnson <mark.johnson@catalyst-eu.net>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
* @covers \qbank_customfields\event\question_deleted_observer
*/
class question_deleted_observer_test extends \advanced_testcase {
/**
* Deleting a question with customfield data should also delete the data.
*
* @return void
*/
public function test_delete_question_with_customfields(): void {
$this->resetAfterTest();
$generator = self::getDataGenerator();
$data = [
'component' => 'qbank_customfields',
'area' => 'question'
];
$categoryid = $generator->create_custom_field_category($data)->get('id');
$generator->create_custom_field(['categoryid' => $categoryid, 'type' => 'text', 'shortname' => 'f1']);
$questiongenerator = $generator->get_plugin_generator('core_question');
[, , , $questions] = $questiongenerator->setup_course_and_questions();
$question = reset($questions);
$customfieldhandler = \qbank_customfields\customfield\question_handler::create();
$questiondata = (object)[
'id' => $question->id,
'customfield_f1' => random_string()
];
$customfieldhandler->instance_form_save($questiondata);
$customdata = $customfieldhandler->get_instance_data($question->id);
$this->assertCount(1, $customdata);
$this->assertEquals($questiondata->customfield_f1, reset($customdata)->get_value());
question_delete_question($question->id);
$customdata = $customfieldhandler->get_instance_data($question->id);
$this->assertCount(1, $customdata);
$this->assertEmpty(reset($customdata)->get_value());
}
}
@@ -0,0 +1,145 @@
<?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 qbank_customfields;
/**
* Class qbank_customfields_question_handler_testcase
*
* @package qbank_customfields
* @copyright 2021 Catalyst IT Australia Pty Ltd
* @author Matt Porritt <mattp@catalyst-au.net>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class question_handler_test extends \advanced_testcase {
/**
* Question setup helper method.
*
* @return int The question id.
* @throws coding_exception
*/
protected function setup_question(): int {
$category = $this->getDataGenerator()->create_category();
$questiongenerator = $this->getDataGenerator()->get_plugin_generator('core_question');
$context = \context_coursecat::instance($category->id);
$questioncategory = $questiongenerator->create_question_category(['contextid' => $context->id]);
$questiondata = ['category' => $questioncategory->id, 'idnumber' => 'q1'];
$question = $questiongenerator->create_question('shortanswer', null, $questiondata);
return $question->id;
}
/**
* Test custom field data.
*/
public function test_get_field_data(): void {
$this->resetAfterTest();
$fieldgenerator = $this->getDataGenerator()->get_plugin_generator('core_customfield');
$instanceid = $this->setup_question();
$fieldvalue = 'test field text';
$categorydata = new \stdClass();
$categorydata->component = 'qbank_customfields';
$categorydata->area = 'question';
$categorydata->name = 'test category';
$customfieldcatid = $fieldgenerator->create_category($categorydata)->get('id');
$field = $fieldgenerator->create_field(['categoryid' => $customfieldcatid, 'type' => 'text', 'shortname' => 'f1']);
$fieldgenerator->add_instance_data($field, $instanceid, $fieldvalue);
// Get the field data.
$customfieldhandler = customfield\question_handler::create();
$fieldinstancedata = $customfieldhandler->get_field_data($field, $instanceid);
$this->assertEquals($categorydata->name, $fieldinstancedata->get_field()->get_category()->get('name'));
$this->assertEquals($fieldvalue, $fieldinstancedata->get_value());
}
/**
* Test getting custom field data for table display.
*/
public function test_display_custom_field_table(): void {
$this->resetAfterTest();
$fieldgenerator = $this->getDataGenerator()->get_plugin_generator('core_customfield');
$instanceid = $this->setup_question();
$fieldvalue = 'test field text';
$categorydata = new \stdClass();
$categorydata->component = 'qbank_customfields';
$categorydata->area = 'question';
$categorydata->name = 'test category';
$customfieldcatid = $fieldgenerator->create_category($categorydata)->get('id');
$field = $fieldgenerator->create_field(['categoryid' => $customfieldcatid, 'type' => 'text', 'shortname' => 'f1']);
$fieldgenerator->add_instance_data($field, $instanceid, $fieldvalue);
// Get the field data.
$customfieldhandler = customfield\question_handler::create();
$fieldinstancedata = $customfieldhandler->get_field_data($field, $instanceid);
$output = $customfieldhandler->display_custom_field_table($fieldinstancedata);
$this->assertStringContainsString($fieldvalue, $output);
}
/**
* Test getting categories and field data for a specific instance.
*/
public function test_get_categories_fields_data(): void {
$this->resetAfterTest();
$fieldgenerator = $this->getDataGenerator()->get_plugin_generator('core_customfield');
$instanceid = $this->setup_question();
$field1value = 'first field text';
$field2value = 'second field text';
$field3value = 'third field text';
$categorydata = new \stdClass();
$categorydata->component = 'qbank_customfields';
$categorydata->area = 'question';
$categorydata->name = 'test category';
$customfieldcat1id = $fieldgenerator->create_category($categorydata)->get('id');
$categorydata->name = 'test category two';
$customfieldcat2id = $fieldgenerator->create_category($categorydata)->get('id');
$field1 = $fieldgenerator->create_field(['categoryid' => $customfieldcat1id, 'type' => 'text', 'shortname' => 'f1']);
$fieldgenerator->add_instance_data($field1, $instanceid, $field1value);
$field2 = $fieldgenerator->create_field(['categoryid' => $customfieldcat1id, 'type' => 'text', 'shortname' => 'f2']);
$fieldgenerator->add_instance_data($field2, $instanceid, $field2value);
$field3 = $fieldgenerator->create_field(['categoryid' => $customfieldcat2id, 'type' => 'text', 'shortname' => 'f3']);
$fieldgenerator->add_instance_data($field3, $instanceid, $field3value);
// Get the field data.
$customfieldhandler = customfield\question_handler::create();
$outputdata = $customfieldhandler->get_categories_fields_data($instanceid);
$this->assertEquals($field1value, $outputdata['test category'][0]['value']);
$this->assertEquals($field2value, $outputdata['test category'][1]['value']);
$this->assertEquals($field3value, $outputdata['test category two'][0]['value']);
// While we're here, lets test the rendering of this data.
$outputhtml = $customfieldhandler->display_custom_categories_fields($outputdata);
$this->assertStringContainsString($field1value, $outputhtml);
$this->assertStringContainsString($field2value, $outputhtml);
$this->assertStringContainsString($field3value, $outputhtml);
}
}