diff --git a/privacy/classes/local/request/transform.php b/privacy/classes/local/request/transform.php index 48c38658b3f..f7d9a6cfd45 100644 --- a/privacy/classes/local/request/transform.php +++ b/privacy/classes/local/request/transform.php @@ -80,4 +80,18 @@ class transform { return get_string('no'); } } + + /** + * Translate a float value which should be between 0.0 and 1.0 into percentage. + * + * @param float $value The value between 0.0 and 1.0. + * @return float|string + */ + public static function percentage(float $value) { + if (is_float($value)) { + return (100 * $value) . '%'; + } else { + return $value; + } + } } diff --git a/question/type/ddimageortext/classes/privacy/provider.php b/question/type/ddimageortext/classes/privacy/provider.php index ab1ebfb4fab..e28ff175cb0 100644 --- a/question/type/ddimageortext/classes/privacy/provider.php +++ b/question/type/ddimageortext/classes/privacy/provider.php @@ -24,23 +24,60 @@ namespace qtype_ddimageortext\privacy; +use core_privacy\local\metadata\collection; +use core_privacy\local\request\transform; +use core_privacy\local\request\writer; + defined('MOODLE_INTERNAL') || die(); /** - * Privacy Subsystem for qtype_ddimageortext implementing null_provider. + * Privacy Subsystem for qtype_ddimageortext implementing user_preference_provider. * * @copyright 2018 Andrew Nicols * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ -class provider implements \core_privacy\local\metadata\null_provider { +class provider implements + // This component has data. + // We need to return default options that have been set a user preferences. + \core_privacy\local\metadata\provider, + \core_privacy\local\request\user_preference_provider +{ /** - * Get the language string identifier with the component's language - * file to explain why this plugin stores no data. + * Returns meta data about this system. * - * @return string + * @param collection $collection The initialised collection to add items to. + * @return collection A listing of user data stored through this system. */ - public static function get_reason() : string { - return 'privacy:metadata'; + public static function get_metadata(collection $collection) : collection { + $collection->add_user_preference('qtype_ddimageortext_defaultmark', 'privacy:preference:defaultmark'); + $collection->add_user_preference('qtype_ddimageortext_penalty', 'privacy:preference:penalty'); + $collection->add_user_preference('qtype_ddimageortext_shuffleanswers', 'privacy:preference:shuffleanswers'); + return $collection; + } + + /** + * Export all user preferences for the plugin. + * + * @param int $userid The userid of the user whose data is to be exported. + */ + public static function export_user_preferences(int $userid) { + $preference = get_user_preferences('qtype_ddimageortext_defaultmark', null, $userid); + if (null !== $preference) { + $desc = get_string('privacy:preference:defaultmark', 'qtype_ddimageortext'); + writer::export_user_preference('qtype_ddimageortext', 'defaultmark', $preference, $desc); + } + + $preference = get_user_preferences('qtype_ddimageortext_penalty', null, $userid); + if (null !== $preference) { + $desc = get_string('privacy:preference:penalty', 'qtype_ddimageortext'); + writer::export_user_preference('qtype_ddimageortext', 'penalty', transform::percentage($preference), $desc); + } + + $preference = get_user_preferences('qtype_ddimageortext_shuffleanswers', null, $userid); + if (null !== $preference) { + $desc = get_string('privacy:preference:shuffleanswers', 'qtype_ddimageortext'); + writer::export_user_preference('qtype_ddimageortext', 'shuffleanswers', transform::yesno($preference), $desc); + } } } diff --git a/question/type/ddimageortext/lang/en/qtype_ddimageortext.php b/question/type/ddimageortext/lang/en/qtype_ddimageortext.php index 674873ee0ce..6a6f9b81acd 100644 --- a/question/type/ddimageortext/lang/en/qtype_ddimageortext.php +++ b/question/type/ddimageortext/lang/en/qtype_ddimageortext.php @@ -63,7 +63,10 @@ $string['pluginnamesummary'] = 'Images or text labels are dragged and dropped in Note: This question type is not accessible to users who are visually impaired.'; $string['previewareaheader'] = 'Preview'; $string['previewareamessage'] = 'Select a background image, specify draggable items and define drop zones on the background image into which they must be dragged.'; -$string['privacy:metadata'] = 'The Drag and drop onto image question type plugin does not store any personal data.'; +$string['privacy:metadata'] = 'Drag and drop onto image question type plugin allows question authors to set default options as user preferences.'; +$string['privacy:preference:defaultmark'] = 'The default mark set for a given question.'; +$string['privacy:preference:penalty'] = 'The penalty for each incorrect try when questions are run using the \'Interactive with multiple tries\' or \'Adaptive mode\' behaviour.'; +$string['privacy:preference:shuffleanswers'] = 'Whether the answers should be automatically shuffled.'; $string['refresh'] = 'Refresh preview'; $string['shuffleimages'] = 'Shuffle drag items each time question is attempted'; $string['summarisechoice'] = '{$a->no}. {$a->text}'; diff --git a/question/type/ddimageortext/tests/privacy_provider_test.php b/question/type/ddimageortext/tests/privacy_provider_test.php new file mode 100644 index 00000000000..24220ec7b89 --- /dev/null +++ b/question/type/ddimageortext/tests/privacy_provider_test.php @@ -0,0 +1,101 @@ +. + +/** + * Privacy provider tests. + * + * @package qtype_ddimageortext + * @copyright 2021 The Open university + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ + +use core_privacy\local\metadata\collection; +use \core_privacy\local\request\user_preference_provider; +use qtype_ddimageortext\privacy\provider; +use core_privacy\local\request\writer; +use core_privacy\local\request\transform; + +defined('MOODLE_INTERNAL') || die(); + +global $CFG; +require_once($CFG->dirroot . '/question/type/ddimageortext/classes/privacy/provider.php'); + +/** + * Privacy provider tests class. + * + * @package qtype_ddimageortext + * @copyright 2021 The Open university + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ +class qtype_ddimageortext_privacy_provider_testcase extends \core_privacy\tests\provider_testcase { + // Include the privacy helper which has assertions on it. + + public function test_get_metadata() { + $collection = new \core_privacy\local\metadata\collection('qtype_ddimageortext'); + $actual = \qtype_ddimageortext\privacy\provider::get_metadata($collection); + $this->assertEquals($collection, $actual); + } + + public function test_export_user_preferences_no_pref() { + $this->resetAfterTest(); + + $user = $this->getDataGenerator()->create_user(); + provider::export_user_preferences($user->id); + $writer = writer::with_context(\context_system::instance()); + $this->assertFalse($writer->has_any_data()); + } + + /** + * Test the export_user_preferences given different inputs + * @dataProvider user_preference_provider + + * @param string $name The name of the user preference to get/set + * @param string $value The value stored in the database + * @param string $expected The expected transformed value + */ + public function test_export_user_preferences($name, $value, $expected) { + $this->resetAfterTest(); + $user = $this->getDataGenerator()->create_user(); + set_user_preference("qtype_ddimageortext_$name", $value, $user); + provider::export_user_preferences($user->id); + $writer = writer::with_context(\context_system::instance()); + $this->assertTrue($writer->has_any_data()); + $preferences = $writer->get_user_preferences('qtype_ddimageortext'); + foreach ($preferences as $key => $pref) { + $preference = get_user_preferences("qtype_ddimageortext_{$key}", null, $user->id); + if ($preference === null) { + continue; + } + $desc = get_string("privacy:preference:{$key}", 'qtype_ddimageortext'); + $this->assertEquals($expected, $pref->value); + $this->assertEquals($desc, $pref->description); + } + } + + /** + * Create an array of valid user preferences for the multiple choice question type. + * + * @return array Array of valid user preferences. + */ + public function user_preference_provider() { + return [ + 'default mark 1' => ['defaultmark', 1, 1], + 'penalty 33.33333%' => ['penalty', 0.3333333, '33.33333%'], + 'shuffle yes' => ['shuffleanswers', 1, 'Yes'], + 'shuffle no' => ['shuffleanswers', 0, 'No'] + ]; + } +} diff --git a/question/type/ddmarker/classes/privacy/provider.php b/question/type/ddmarker/classes/privacy/provider.php index 3a2ffa6aeac..a99efe153b5 100644 --- a/question/type/ddmarker/classes/privacy/provider.php +++ b/question/type/ddmarker/classes/privacy/provider.php @@ -24,23 +24,60 @@ namespace qtype_ddmarker\privacy; +use core_privacy\local\metadata\collection; +use core_privacy\local\request\transform; +use core_privacy\local\request\writer; + defined('MOODLE_INTERNAL') || die(); /** - * Privacy Subsystem for qtype_ddmarker implementing null_provider. + * Privacy Subsystem for qtype_ddmarker implementing user_preference_provider. * * @copyright 2018 Andrew Nicols * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ -class provider implements \core_privacy\local\metadata\null_provider { +class provider implements + // This component has data. + // We need to return default options that have been set a user preferences. + \core_privacy\local\metadata\provider, + \core_privacy\local\request\user_preference_provider +{ /** - * Get the language string identifier with the component's language - * file to explain why this plugin stores no data. + * Returns meta data about this system. * - * @return string + * @param collection $collection The initialised collection to add items to. + * @return collection A listing of user data stored through this system. */ - public static function get_reason() : string { - return 'privacy:metadata'; + public static function get_metadata(collection $collection) : collection { + $collection->add_user_preference('qtype_ddmarker_defaultmark', 'privacy:preference:defaultmark'); + $collection->add_user_preference('qtype_ddmarker_penalty', 'privacy:preference:penalty'); + $collection->add_user_preference('qtype_ddmarker_shuffleanswers', 'privacy:preference:shuffleanswers'); + return $collection; + } + + /** + * Export all user preferences for the plugin. + * + * @param int $userid The userid of the user whose data is to be exported. + */ + public static function export_user_preferences(int $userid) { + $preference = get_user_preferences('qtype_ddmarker_defaultmark', null, $userid); + if (null !== $preference) { + $desc = get_string('privacy:preference:defaultmark', 'qtype_ddmarker'); + writer::export_user_preference('qtype_ddmarker', 'defaultmark', $preference, $desc); + } + + $preference = get_user_preferences('qtype_ddmarker_penalty', null, $userid); + if (null !== $preference) { + $desc = get_string('privacy:preference:penalty', 'qtype_ddmarker'); + writer::export_user_preference('qtype_ddmarker', 'penalty', transform::percentage($preference), $desc); + } + + $preference = get_user_preferences('qtype_ddmarker_shuffleanswers', null, $userid); + if (null !== $preference) { + $desc = get_string('privacy:preference:shuffleanswers', 'qtype_ddmarker'); + writer::export_user_preference('qtype_ddmarker', 'shuffleanswers', transform::yesno($preference), $desc); + } } } diff --git a/question/type/ddmarker/lang/en/qtype_ddmarker.php b/question/type/ddmarker/lang/en/qtype_ddmarker.php index 28d7d6f78d3..e1461580955 100644 --- a/question/type/ddmarker/lang/en/qtype_ddmarker.php +++ b/question/type/ddmarker/lang/en/qtype_ddmarker.php @@ -81,7 +81,10 @@ $string['pluginnamesummary'] = 'Markers are dragged and dropped onto a backgroun Note: This question type is not accessible to users who are visually impaired.'; $string['previewareaheader'] = 'Preview'; $string['previewareamessage'] = 'Select a background image file, enter text labels for markers and define the drop zones on the background image to which they must be dragged.'; -$string['privacy:metadata'] = 'The Drag and drop markers question type plugin does not store any personal data.'; +$string['privacy:metadata'] = 'Drag and drop markers question type plugin allows question authors to set default options as user preferences.'; +$string['privacy:preference:defaultmark'] = 'The default mark set for a given question.'; +$string['privacy:preference:penalty'] = 'The penalty for each incorrect try when questions are run using the \'Interactive with multiple tries\' or \'Adaptive mode\' behaviour.'; +$string['privacy:preference:shuffleanswers'] = 'Whether the answers should be automatically shuffled.'; $string['refresh'] = 'Refresh preview'; $string['clearwrongparts'] = 'Move incorrectly placed markers back to default start position below image'; $string['shape'] = 'Shape'; diff --git a/question/type/ddmarker/tests/privacy_provider_test.php b/question/type/ddmarker/tests/privacy_provider_test.php new file mode 100644 index 00000000000..a842421fcbf --- /dev/null +++ b/question/type/ddmarker/tests/privacy_provider_test.php @@ -0,0 +1,101 @@ +. + +/** + * Privacy provider tests. + * + * @package qtype_ddmarker + * @copyright 2021 The Open university + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ + +use core_privacy\local\metadata\collection; +use \core_privacy\local\request\user_preference_provider; +use qtype_ddmarker\privacy\provider; +use core_privacy\local\request\writer; +use core_privacy\local\request\transform; + +defined('MOODLE_INTERNAL') || die(); + +global $CFG; +require_once($CFG->dirroot . '/question/type/ddmarker/classes/privacy/provider.php'); + +/** + * Privacy provider tests class. + * + * @package qtype_ddmarker + * @copyright 2021 The Open university + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ +class qtype_ddmarker_privacy_provider_testcase extends \core_privacy\tests\provider_testcase { + // Include the privacy helper which has assertions on it. + + public function test_get_metadata() { + $collection = new \core_privacy\local\metadata\collection('qtype_ddmarker'); + $actual = \qtype_ddmarker\privacy\provider::get_metadata($collection); + $this->assertEquals($collection, $actual); + } + + public function test_export_user_preferences_no_pref() { + $this->resetAfterTest(); + + $user = $this->getDataGenerator()->create_user(); + provider::export_user_preferences($user->id); + $writer = writer::with_context(\context_system::instance()); + $this->assertFalse($writer->has_any_data()); + } + + /** + * Test the export_user_preferences given different inputs + * @dataProvider user_preference_provider + + * @param string $name The name of the user preference to get/set + * @param string $value The value stored in the database + * @param string $expected The expected transformed value + */ + public function test_export_user_preferences($name, $value, $expected) { + $this->resetAfterTest(); + $user = $this->getDataGenerator()->create_user(); + set_user_preference("qtype_ddmarker_$name", $value, $user); + provider::export_user_preferences($user->id); + $writer = writer::with_context(\context_system::instance()); + $this->assertTrue($writer->has_any_data()); + $preferences = $writer->get_user_preferences('qtype_ddmarker'); + foreach ($preferences as $key => $pref) { + $preference = get_user_preferences("qtype_ddmarker_{$key}", null, $user->id); + if ($preference === null) { + continue; + } + $desc = get_string("privacy:preference:{$key}", 'qtype_ddmarker'); + $this->assertEquals($expected, $pref->value); + $this->assertEquals($desc, $pref->description); + } + } + + /** + * Create an array of valid user preferences for the multiple choice question type. + * + * @return array Array of valid user preferences. + */ + public function user_preference_provider() { + return [ + 'default mark 1.5' => ['defaultmark', 1.5, 1.5], + 'penalty 33.33333%' => ['penalty', 0.3333333, '33.33333%'], + 'shuffle yes' => ['shuffleanswers', 1, 'Yes'], + 'shuffle no' => ['shuffleanswers', 0, 'No'] + ]; + } +} diff --git a/question/type/ddwtos/classes/privacy/provider.php b/question/type/ddwtos/classes/privacy/provider.php index 8845e44feb7..ddd1590518d 100644 --- a/question/type/ddwtos/classes/privacy/provider.php +++ b/question/type/ddwtos/classes/privacy/provider.php @@ -24,23 +24,60 @@ namespace qtype_ddwtos\privacy; +use core_privacy\local\metadata\collection; +use core_privacy\local\request\transform; +use core_privacy\local\request\writer; + defined('MOODLE_INTERNAL') || die(); /** - * Privacy Subsystem for qtype_ddwtos implementing null_provider. + * Privacy Subsystem for qtype_ddwtos implementing user_preference_provider. * * @copyright 2018 Andrew Nicols * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ -class provider implements \core_privacy\local\metadata\null_provider { +class provider implements + // This component has data. + // We need to return default options that have been set a user preferences. + \core_privacy\local\metadata\provider, + \core_privacy\local\request\user_preference_provider +{ /** - * Get the language string identifier with the component's language - * file to explain why this plugin stores no data. + * Returns meta data about this system. * - * @return string + * @param collection $collection The initialised collection to add items to. + * @return collection A listing of user data stored through this system. */ - public static function get_reason() : string { - return 'privacy:metadata'; + public static function get_metadata(collection $collection) : collection { + $collection->add_user_preference('qtype_ddwtos_defaultmark', 'privacy:preference:defaultmark'); + $collection->add_user_preference('qtype_ddwtos_penalty', 'privacy:preference:penalty'); + $collection->add_user_preference('qtype_ddwtos_shuffleanswers', 'privacy:preference:shuffleanswers'); + return $collection; + } + + /** + * Export all user preferences for the plugin. + * + * @param int $userid The userid of the user whose data is to be exported. + */ + public static function export_user_preferences(int $userid) { + $preference = get_user_preferences('qtype_ddwtos_defaultmark', null, $userid); + if (null !== $preference) { + $desc = get_string('privacy:preference:defaultmark', 'qtype_ddwtos'); + writer::export_user_preference('qtype_ddwtos', 'defaultmark', $preference, $desc); + } + + $preference = get_user_preferences('qtype_ddwtos_penalty', null, $userid); + if (null !== $preference) { + $desc = get_string('privacy:preference:penalty', 'qtype_ddwtos'); + writer::export_user_preference('qtype_ddwtos', 'penalty', transform::percentage($preference), $desc); + } + + $preference = get_user_preferences('qtype_ddwtos_shuffleanswers', null, $userid); + if (null !== $preference) { + $desc = get_string('privacy:preference:shuffleanswers', 'qtype_ddwtos'); + writer::export_user_preference('qtype_ddwtos', 'shuffleanswers', transform::yesno($preference), $desc); + } } } diff --git a/question/type/ddwtos/lang/en/qtype_ddwtos.php b/question/type/ddwtos/lang/en/qtype_ddwtos.php index fd4b3dbbdc9..e25433ab2a2 100644 --- a/question/type/ddwtos/lang/en/qtype_ddwtos.php +++ b/question/type/ddwtos/lang/en/qtype_ddwtos.php @@ -34,4 +34,7 @@ $string['pluginname_link'] = 'question/type/ddwtos'; $string['pluginnameadding'] = 'Adding a drag and drop into text'; $string['pluginnameediting'] = 'Editing a drag and drop into text'; $string['pluginnamesummary'] = 'Missing words in the question text are filled in using drag and drop.'; -$string['privacy:metadata'] = 'The Drag and drop into text question type plugin does not store any personal data.'; +$string['privacy:metadata'] = 'Drag and drop into text question type plugin allows question authors to set default options as user preferences.'; +$string['privacy:preference:defaultmark'] = 'The default mark set for a given question.'; +$string['privacy:preference:penalty'] = 'The penalty for each incorrect try when questions are run using the \'Interactive with multiple tries\' or \'Adaptive mode\' behaviour.'; +$string['privacy:preference:shuffleanswers'] = 'Whether the answers should be automatically shuffled.'; diff --git a/question/type/ddwtos/tests/privacy_provider_test.php b/question/type/ddwtos/tests/privacy_provider_test.php new file mode 100644 index 00000000000..36f5cc1c42c --- /dev/null +++ b/question/type/ddwtos/tests/privacy_provider_test.php @@ -0,0 +1,101 @@ +. + +/** + * Privacy provider tests. + * + * @package qtype_ddwtos + * @copyright 2021 The Open university + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ + +use core_privacy\local\metadata\collection; +use \core_privacy\local\request\user_preference_provider; +use qtype_ddwtos\privacy\provider; +use core_privacy\local\request\writer; +use core_privacy\local\request\transform; + +defined('MOODLE_INTERNAL') || die(); + +global $CFG; +require_once($CFG->dirroot . '/question/type/ddwtos/classes/privacy/provider.php'); + +/** + * Privacy provider tests class. + * + * @package qtype_ddwtos + * @copyright 2021 The Open university + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ +class qtype_ddwtos_privacy_provider_testcase extends \core_privacy\tests\provider_testcase { + // Include the privacy helper which has assertions on it. + + public function test_get_metadata() { + $collection = new \core_privacy\local\metadata\collection('qtype_ddwtos'); + $actual = \qtype_ddwtos\privacy\provider::get_metadata($collection); + $this->assertEquals($collection, $actual); + } + + public function test_export_user_preferences_no_pref() { + $this->resetAfterTest(); + + $user = $this->getDataGenerator()->create_user(); + provider::export_user_preferences($user->id); + $writer = writer::with_context(\context_system::instance()); + $this->assertFalse($writer->has_any_data()); + } + + /** + * Test the export_user_preferences given different inputs + * @dataProvider user_preference_provider + + * @param string $name The name of the user preference to get/set + * @param string $value The value stored in the database + * @param string $expected The expected transformed value + */ + public function test_export_user_preferences($name, $value, $expected) { + $this->resetAfterTest(); + $user = $this->getDataGenerator()->create_user(); + set_user_preference("qtype_ddwtos_$name", $value, $user); + provider::export_user_preferences($user->id); + $writer = writer::with_context(\context_system::instance()); + $this->assertTrue($writer->has_any_data()); + $preferences = $writer->get_user_preferences('qtype_ddwtos'); + foreach ($preferences as $key => $pref) { + $preference = get_user_preferences("qtype_ddwtos_{$key}", null, $user->id); + if ($preference === null) { + continue; + } + $desc = get_string("privacy:preference:{$key}", 'qtype_ddwtos'); + $this->assertEquals($expected, $pref->value); + $this->assertEquals($desc, $pref->description); + } + } + + /** + * Create an array of valid user preferences for the multiple choice question type. + * + * @return array Array of valid user preferences. + */ + public function user_preference_provider() { + return [ + 'default mark 2' => ['defaultmark', 2, 2], + 'penalty 33.33333%' => ['penalty', 0.3333333, '33.33333%'], + 'shuffle yes' => ['shuffleanswers', 1, 'Yes'], + 'shuffle no' => ['shuffleanswers', 0, 'No'] + ]; + } +} diff --git a/question/type/essay/classes/privacy/provider.php b/question/type/essay/classes/privacy/provider.php index 15d757a0929..53915397437 100644 --- a/question/type/essay/classes/privacy/provider.php +++ b/question/type/essay/classes/privacy/provider.php @@ -24,23 +24,160 @@ namespace qtype_essay\privacy; +use \core_privacy\local\metadata\collection; +use \core_privacy\local\request\user_preference_provider; +use \core_privacy\local\request\writer; + defined('MOODLE_INTERNAL') || die(); /** - * Privacy Subsystem for qtype_essay implementing null_provider. + * Privacy Subsystem for qtype_essay implementing user_preference_provider. * * @copyright 2018 Andrew Nicols * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ -class provider implements \core_privacy\local\metadata\null_provider { +class provider implements + // This component has data. + // We need to return default options that have been set a user preferences. + \core_privacy\local\metadata\provider, + \core_privacy\local\request\user_preference_provider +{ /** - * Get the language string identifier with the component's language - * file to explain why this plugin stores no data. + * Returns meta data about this system. * - * @return string + * @param collection $collection The initialised collection to add items to. + * @return collection A listing of user data stored through this system. */ - public static function get_reason() : string { - return 'privacy:metadata'; + public static function get_metadata(collection $collection) : collection { + $collection->add_user_preference('qtype_essay_defaultmark', 'privacy:preference:defaultmark'); + $collection->add_user_preference('qtype_essay_responseformat', 'privacy:preference:responseformat'); + $collection->add_user_preference('qtype_essay_responserequired', 'privacy:preference:responserequired'); + $collection->add_user_preference('qtype_essay_responsefieldlines', 'privacy:preference:responsefieldlines'); + $collection->add_user_preference('qtype_essay_attachments', 'privacy:preference:attachments'); + $collection->add_user_preference('qtype_essay_attachmentsrequired', 'privacy:preference:attachmentsrequired'); + $collection->add_user_preference('qtype_essay_maxbytes', 'privacy:preference:maxbytes'); + return $collection; + } + + /** + * Export all user preferences for the plugin. + * + * @param int $userid The userid of the user whose data is to be exported. + */ + public static function export_user_preferences(int $userid) { + $preference = get_user_preferences('qtype_essay_defaultmark', null, $userid); + if (null !== $preference) { + $desc = get_string('privacy:preference:defaultmark', 'qtype_essay'); + writer::export_user_preference('qtype_essay', 'defaultmark', $preference, $desc); + } + + $preference = get_user_preferences('qtype_essay_responseformat', null, $userid); + if (null !== $preference) { + switch($preference) { + case 'editor': + $stringvalue = get_string('formateditor', 'qtype_essay'); + break; + case 'editorfilepicker': + $stringvalue = get_string('formateditorfilepicker', 'qtype_essay'); + break; + case 'plain': + $stringvalue = get_string('formatplain', 'qtype_essay'); + break; + case 'monospaced': + $stringvalue = get_string('formatmonospaced', 'qtype_essay'); + break; + case 'noinline': + $stringvalue = get_string('formatnoinline', 'qtype_essay'); + break; + default: + $stringvalue = get_string('formateditor', 'qtype_essay'); + break; + } + $desc = get_string('privacy:preference:responseformat', 'qtype_essay'); + writer::export_user_preference('qtype_essay', 'responseformat', $stringvalue, $desc); + } + + $preference = get_user_preferences('qtype_essay_responserequired', null, $userid); + if (null !== $preference) { + if ($preference) { + $stringvalue = get_string('responseisrequired', 'qtype_essay'); + } else { + $stringvalue = get_string('responsenotrequired', 'qtype_essay'); + } + $desc = get_string('privacy:preference:responserequired', 'qtype_essay'); + writer::export_user_preference('qtype_essay', 'responserequired', $stringvalue, $desc); + } + + $preference = get_user_preferences('qtype_essay_responsefieldlines', null, $userid); + if (null !== $preference) { + $desc = get_string('privacy:preference:responsefieldlines', 'qtype_essay'); + writer::export_user_preference('qtype_essay', 'responsefieldlines', + get_string('nlines', 'qtype_essay', $preference), $desc); + } + $preference = get_user_preferences('qtype_essay_attachments', null, $userid); + if (null !== $preference) { + if ($preference == 0) { + $stringvalue = get_string('no'); + } else if ($preference == -1) { + $stringvalue = get_string('unlimited'); + } else { + $stringvalue = $preference; + } + $desc = get_string('privacy:preference:attachments', 'qtype_essay'); + writer::export_user_preference('qtype_essay', 'attachments', $stringvalue, $desc); + } + + $preference = get_user_preferences('qtype_essay_attachmentsrequired', null, $userid); + if (null !== $preference) { + if ($preference == 0) { + $stringvalue = get_string('attachmentsoptional', 'qtype_essay'); + } else { + $stringvalue = $preference; + } + $desc = get_string('privacy:preference:attachmentsrequired', 'qtype_essay'); + writer::export_user_preference('qtype_essay', 'attachmentsrequired', $stringvalue, $desc); + } + + $preference = get_user_preferences('qtype_essay_maxbytes', null, $userid); + if (null !== $preference) { + switch ($preference) { + case 52428800: + $stringvalue = '50MB'; + break; + case 20971520: + $stringvalue = '20MB'; + break; + case 10485760: + $stringvalue = '10MB'; + break; + case 5242880: + $stringvalue = '5MB'; + break; + case 2097152: + $stringvalue = '2MB'; + break; + case 1048576: + $stringvalue = '1MB'; + break; + case 512000: + $stringvalue = '500KB'; + break; + case 102400: + $stringvalue = '100KB'; + break; + case 51200: + $stringvalue = '50KB'; + break; + case 10240: + $stringvalue = '10KB'; + break; + default: + $stringvalue = '50MB'; + break; + } + $desc = get_string('privacy:preference:maxbytes', 'qtype_essay'); + writer::export_user_preference('qtype_essay', 'maxbytes', $stringvalue, $desc); + } } } diff --git a/question/type/essay/lang/en/qtype_essay.php b/question/type/essay/lang/en/qtype_essay.php index e98e2920fc6..18d5d2c8397 100644 --- a/question/type/essay/lang/en/qtype_essay.php +++ b/question/type/essay/lang/en/qtype_essay.php @@ -60,7 +60,14 @@ $string['pluginname_link'] = 'question/type/essay'; $string['pluginnameadding'] = 'Adding an Essay question'; $string['pluginnameediting'] = 'Editing an Essay question'; $string['pluginnamesummary'] = 'Allows a response of a file upload and/or online text. This must then be graded manually.'; -$string['privacy:metadata'] = 'The Essay question type plugin does not store any personal data.'; +$string['privacy:metadata'] = 'Essay question type plugin allows question authors to set default options as user preferences.'; +$string['privacy:preference:defaultmark'] = 'The default mark set for a given question.'; +$string['privacy:preference:responseformat'] = 'What is the response forma (HTML editor, Plain test, ect.)?'; +$string['privacy:preference:responserequired'] = 'Whether the student is required to enter text or the text input ias optional.'; +$string['privacy:preference:responsefieldlines'] = 'Number of lines indicating the size of the input box (textarea).'; +$string['privacy:preference:attachments'] = 'Number of allowed attachments.'; +$string['privacy:preference:attachmentsrequired'] = 'Number of required attachments.'; +$string['privacy:preference:maxbytes'] = 'Maximum file size.'; $string['responsefieldlines'] = 'Input box size'; $string['responseformat'] = 'Response format'; $string['responseoptions'] = 'Response Options'; diff --git a/question/type/essay/tests/privacy_provider_test.php b/question/type/essay/tests/privacy_provider_test.php new file mode 100644 index 00000000000..004da615a40 --- /dev/null +++ b/question/type/essay/tests/privacy_provider_test.php @@ -0,0 +1,113 @@ +. + +/** + * Privacy provider tests. + * + * @package qtype_essay + * @copyright 2021 The Open university + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ + +use core_privacy\local\metadata\collection; +use \core_privacy\local\request\user_preference_provider; +use qtype_essay\privacy\provider; +use core_privacy\local\request\writer; +use core_privacy\local\request\transform; + +defined('MOODLE_INTERNAL') || die(); + +global $CFG; +require_once($CFG->dirroot . '/question/type/essay/classes/privacy/provider.php'); + +/** + * Privacy provider tests class. + * + * @package qtype_essay + * @copyright 2021 The Open university + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ +class qtype_essay_privacy_provider_testcase extends \core_privacy\tests\provider_testcase { + // Include the privacy helper which has assertions on it. + + public function test_get_metadata() { + $collection = new \core_privacy\local\metadata\collection('qtype_essay'); + $actual = \qtype_essay\privacy\provider::get_metadata($collection); + $this->assertEquals($collection, $actual); + } + + public function test_export_user_preferences_no_pref() { + $this->resetAfterTest(); + + $user = $this->getDataGenerator()->create_user(); + provider::export_user_preferences($user->id); + $writer = writer::with_context(\context_system::instance()); + $this->assertFalse($writer->has_any_data()); + } + + /** + * Test the export_user_preferences given different inputs + * @dataProvider user_preference_provider + + * @param string $name The name of the user preference to get/set + * @param string $value The value stored in the database + * @param string $expected The expected transformed value + */ + public function test_export_user_preferences($name, $value, $expected) { + $this->resetAfterTest(); + $user = $this->getDataGenerator()->create_user(); + set_user_preference("qtype_essay_$name", $value, $user); + provider::export_user_preferences($user->id); + $writer = writer::with_context(\context_system::instance()); + $this->assertTrue($writer->has_any_data()); + $preferences = $writer->get_user_preferences('qtype_essay'); + foreach ($preferences as $key => $pref) { + $preference = get_user_preferences("qtype_essay_{$key}", null, $user->id); + if ($preference === null) { + continue; + } + $desc = get_string("privacy:preference:{$key}", 'qtype_essay'); + $this->assertEquals($expected, $pref->value); + $this->assertEquals($desc, $pref->description); + } + } + + /** + * Create an array of valid user preferences for the multiple choice question type. + * + * @return array Array of valid user preferences. + */ + public function user_preference_provider() { + return [ + 'default mark 2' => ['defaultmark', 2, 2], + 'responseformat editror ' => ['responseformat', 'editor', get_string('formateditor', 'qtype_essay')], + 'responseformat editor and filepicker ' => + ['responseformat', 'editorfilepicker', get_string('formateditorfilepicker', 'qtype_essay')], + 'responseformat plain ' => ['responseformat', 'plain', get_string('formatplain', 'qtype_essay')], + 'responseformat monospaced ' => ['responseformat', 'monospaced', get_string('formatmonospaced', 'qtype_essay')], + 'responseformat noinline ' => ['responseformat', 'noinline', get_string('formatnoinline', 'qtype_essay')], + 'responserequired yes' => ['responserequired', 1, get_string('responseisrequired', 'qtype_essay')], + 'responserequired no ' => ['responserequired', 0, get_string('responsenotrequired', 'qtype_essay')], + 'responsefieldlines 10' => ['responsefieldlines', 10, '10 lines'], + 'attachments none' => ['attachments', 0, get_string('no')], + 'attachments 3' => ['attachments', 3, '3'], + 'attachments unlimited' => ['attachments', -1, get_string('unlimited')], + 'attachmentsrequired optional' => ['attachmentsrequired', 0, get_string('attachmentsoptional', 'qtype_essay')], + 'attachmentsrequired 1' => ['attachmentsrequired', 1, '1'], + 'maxbytes 50KB' => ['maxbytes', 51200, '50KB'] + ]; + } +} diff --git a/question/type/gapselect/classes/privacy/provider.php b/question/type/gapselect/classes/privacy/provider.php index 0bd152d1f09..a9aa3cbb45a 100644 --- a/question/type/gapselect/classes/privacy/provider.php +++ b/question/type/gapselect/classes/privacy/provider.php @@ -24,23 +24,60 @@ namespace qtype_gapselect\privacy; +use core_privacy\local\metadata\collection; +use core_privacy\local\request\transform; +use core_privacy\local\request\writer; + defined('MOODLE_INTERNAL') || die(); /** - * Privacy Subsystem for qtype_gapselect implementing null_provider. + * Privacy Subsystem for qtype_gapselect implementing user_preference_provider. * * @copyright 2018 Andrew Nicols * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ -class provider implements \core_privacy\local\metadata\null_provider { +class provider implements + // This component has data. + // We need to return default options that have been set a user preferences. + \core_privacy\local\metadata\provider, + \core_privacy\local\request\user_preference_provider +{ /** - * Get the language string identifier with the component's language - * file to explain why this plugin stores no data. + * Returns meta data about this system. * - * @return string + * @param collection $collection The initialised collection to add items to. + * @return collection A listing of user data stored through this system. */ - public static function get_reason() : string { - return 'privacy:metadata'; + public static function get_metadata(collection $collection) : collection { + $collection->add_user_preference('qtype_gapselect_defaultmark', 'privacy:preference:defaultmark'); + $collection->add_user_preference('qtype_gapselect_penalty', 'privacy:preference:penalty'); + $collection->add_user_preference('qtype_gapselect_shuffleanswers', 'privacy:preference:shuffleanswers'); + return $collection; + } + + /** + * Export all user preferences for the plugin. + * + * @param int $userid The userid of the user whose data is to be exported. + */ + public static function export_user_preferences(int $userid) { + $preference = get_user_preferences('qtype_gapselect_defaultmark', null, $userid); + if (null !== $preference) { + $desc = get_string('privacy:preference:defaultmark', 'qtype_gapselect'); + writer::export_user_preference('qtype_gapselect', 'defaultmark', $preference, $desc); + } + + $preference = get_user_preferences('qtype_gapselect_penalty', null, $userid); + if (null !== $preference) { + $desc = get_string('privacy:preference:penalty', 'qtype_gapselect'); + writer::export_user_preference('qtype_gapselect', 'penalty', transform::percentage($preference), $desc); + } + + $preference = get_user_preferences('qtype_gapselect_shuffleanswers', null, $userid); + if (null !== $preference) { + $desc = get_string('privacy:preference:shuffleanswers', 'qtype_gapselect'); + writer::export_user_preference('qtype_gapselect', 'shuffleanswers', transform::yesno($preference), $desc); + } } } diff --git a/question/type/gapselect/lang/en/qtype_gapselect.php b/question/type/gapselect/lang/en/qtype_gapselect.php index d5c64da09da..81b74549728 100644 --- a/question/type/gapselect/lang/en/qtype_gapselect.php +++ b/question/type/gapselect/lang/en/qtype_gapselect.php @@ -41,7 +41,10 @@ $string['pluginname_link'] = 'question/type/gapselect'; $string['pluginnameadding'] = 'Adding a select missing words question'; $string['pluginnameediting'] = 'Editing a select missing words question'; $string['pluginnamesummary'] = 'Missing words in the question text are filled in using drop-down menus.'; -$string['privacy:metadata'] = 'The Select missing words plugin does not store any personal data.'; +$string['privacy:metadata'] = 'Select missing words question type plugin allows question authors to set default options as user preferences.'; +$string['privacy:preference:defaultmark'] = 'The default mark set for a given question.'; +$string['privacy:preference:penalty'] = 'The penalty for each incorrect try when questions are run using the \'Interactive with multiple tries\' or \'Adaptive mode\' behaviour.'; +$string['privacy:preference:shuffleanswers'] = 'Whether the answers should be automatically shuffled.'; $string['shuffle'] = 'Shuffle'; $string['tagsnotallowed'] = '{$a->tag} is not allowed. (Only {$a->allowed} are permitted.)'; $string['tagsnotallowedatall'] = '{$a->tag} is not allowed. (No HTML is allowed here.)'; diff --git a/question/type/gapselect/tests/privacy_provider_test.php b/question/type/gapselect/tests/privacy_provider_test.php new file mode 100644 index 00000000000..7e96cd1407a --- /dev/null +++ b/question/type/gapselect/tests/privacy_provider_test.php @@ -0,0 +1,101 @@ +. + +/** + * Privacy provider tests. + * + * @package qtype_gapselect + * @copyright 2021 The Open university + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ + +use core_privacy\local\metadata\collection; +use \core_privacy\local\request\user_preference_provider; +use qtype_gapselect\privacy\provider; +use core_privacy\local\request\writer; +use core_privacy\local\request\transform; + +defined('MOODLE_INTERNAL') || die(); + +global $CFG; +require_once($CFG->dirroot . '/question/type/gapselect/classes/privacy/provider.php'); + +/** + * Privacy provider tests class. + * + * @package qtype_gapselect + * @copyright 2021 The Open university + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ +class qtype_gapselect_privacy_provider_testcase extends \core_privacy\tests\provider_testcase { + // Include the privacy helper which has assertions on it. + + public function test_get_metadata() { + $collection = new \core_privacy\local\metadata\collection('qtype_gapselect'); + $actual = \qtype_gapselect\privacy\provider::get_metadata($collection); + $this->assertEquals($collection, $actual); + } + + public function test_export_user_preferences_no_pref() { + $this->resetAfterTest(); + + $user = $this->getDataGenerator()->create_user(); + provider::export_user_preferences($user->id); + $writer = writer::with_context(\context_system::instance()); + $this->assertFalse($writer->has_any_data()); + } + + /** + * Test the export_user_preferences given different inputs + * @dataProvider user_preference_provider + + * @param string $name The name of the user preference to get/set + * @param string $value The value stored in the database + * @param string $expected The expected transformed value + */ + public function test_export_user_preferences($name, $value, $expected) { + $this->resetAfterTest(); + $user = $this->getDataGenerator()->create_user(); + set_user_preference("qtype_gapselect_$name", $value, $user); + provider::export_user_preferences($user->id); + $writer = writer::with_context(\context_system::instance()); + $this->assertTrue($writer->has_any_data()); + $preferences = $writer->get_user_preferences('qtype_gapselect'); + foreach ($preferences as $key => $pref) { + $preference = get_user_preferences("qtype_gapselect_{$key}", null, $user->id); + if ($preference === null) { + continue; + } + $desc = get_string("privacy:preference:{$key}", 'qtype_gapselect'); + $this->assertEquals($expected, $pref->value); + $this->assertEquals($desc, $pref->description); + } + } + + /** + * Create an array of valid user preferences for the multiple choice question type. + * + * @return array Array of valid user preferences. + */ + public function user_preference_provider() { + return [ + 'default mark 1.5' => ['defaultmark', 1.5, 1.5], + 'penalty 25%' => ['penalty', 0.2500000, '25%'], + 'shuffle yes' => ['shuffleanswers', 1, 'Yes'], + 'shuffle no' => ['shuffleanswers', 0, 'No'] + ]; + } +} diff --git a/question/type/match/classes/privacy/provider.php b/question/type/match/classes/privacy/provider.php index 4fd70121cde..e4d8cb99998 100644 --- a/question/type/match/classes/privacy/provider.php +++ b/question/type/match/classes/privacy/provider.php @@ -24,23 +24,60 @@ namespace qtype_match\privacy; +use core_privacy\local\metadata\collection; +use core_privacy\local\request\transform; +use core_privacy\local\request\writer; + defined('MOODLE_INTERNAL') || die(); /** - * Privacy Subsystem for qtype_match implementing null_provider. + * Privacy Subsystem for qtype_match implementing user_preference_provider. * * @copyright 2018 Andrew Nicols * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ -class provider implements \core_privacy\local\metadata\null_provider { +class provider implements + // This component has data. + // We need to return default options that have been set a user preferences. + \core_privacy\local\metadata\provider, + \core_privacy\local\request\user_preference_provider +{ /** - * Get the language string identifier with the component's language - * file to explain why this plugin stores no data. + * Returns meta data about this system. * - * @return string + * @param collection $collection The initialised collection to add items to. + * @return collection A listing of user data stored through this system. */ - public static function get_reason() : string { - return 'privacy:metadata'; + public static function get_metadata(collection $collection) : collection { + $collection->add_user_preference('qtype_match_defaultmark', 'privacy:preference:defaultmark'); + $collection->add_user_preference('qtype_match_penalty', 'privacy:preference:penalty'); + $collection->add_user_preference('qtype_match_shuffleanswers', 'privacy:preference:shuffleanswers'); + return $collection; + } + + /** + * Export all user preferences for the plugin. + * + * @param int $userid The userid of the user whose data is to be exported. + */ + public static function export_user_preferences(int $userid) { + $preference = get_user_preferences('qtype_match_defaultmark', null, $userid); + if (null !== $preference) { + $desc = get_string('privacy:preference:defaultmark', 'qtype_match'); + writer::export_user_preference('qtype_match', 'defaultmark', $preference, $desc); + } + + $preference = get_user_preferences('qtype_match_penalty', null, $userid); + if (null !== $preference) { + $desc = get_string('privacy:preference:penalty', 'qtype_match'); + writer::export_user_preference('qtype_match', 'penalty', transform::percentage($preference), $desc); + } + + $preference = get_user_preferences('qtype_match_shuffleanswers', null, $userid); + if (null !== $preference) { + $desc = get_string('privacy:preference:shuffleanswers', 'qtype_match'); + writer::export_user_preference('qtype_match', 'shuffleanswers', transform::yesno($preference), $desc); + } } } diff --git a/question/type/match/lang/en/qtype_match.php b/question/type/match/lang/en/qtype_match.php index 8d20a72aa5c..0addfab235f 100644 --- a/question/type/match/lang/en/qtype_match.php +++ b/question/type/match/lang/en/qtype_match.php @@ -42,4 +42,7 @@ $string['pluginname_link'] = 'question/type/match'; $string['pluginnameadding'] = 'Adding a Matching question'; $string['pluginnameediting'] = 'Editing a Matching question'; $string['pluginnamesummary'] = 'The answer to each of a number of sub-question must be selected from a list of possibilities.'; -$string['privacy:metadata'] = 'The Matching question type plugin does not store any personal data.'; +$string['privacy:metadata'] = 'Matching question type plugin allows question authors to set default options as user preferences.'; +$string['privacy:preference:defaultmark'] = 'The default mark set for a given question.'; +$string['privacy:preference:penalty'] = 'The penalty for each incorrect try when questions are run using the \'Interactive with multiple tries\' or \'Adaptive mode\' behaviour.'; +$string['privacy:preference:shuffleanswers'] = 'Whether the answers should be automatically shuffled.'; diff --git a/question/type/match/tests/privacy_provider_test.php b/question/type/match/tests/privacy_provider_test.php new file mode 100644 index 00000000000..3c5c5dfa956 --- /dev/null +++ b/question/type/match/tests/privacy_provider_test.php @@ -0,0 +1,101 @@ +. + +/** + * Privacy provider tests. + * + * @package qtype_match + * @copyright 2021 The Open university + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ + +use core_privacy\local\metadata\collection; +use \core_privacy\local\request\user_preference_provider; +use qtype_match\privacy\provider; +use core_privacy\local\request\writer; +use core_privacy\local\request\transform; + +defined('MOODLE_INTERNAL') || die(); + +global $CFG; +require_once($CFG->dirroot . '/question/type/match/classes/privacy/provider.php'); + +/** + * Privacy provider tests class. + * + * @package qtype_match + * @copyright 2021 The Open university + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ +class qtype_match_privacy_provider_testcase extends \core_privacy\tests\provider_testcase { + // Include the privacy helper which has assertions on it. + + public function test_get_metadata() { + $collection = new \core_privacy\local\metadata\collection('qtype_match'); + $actual = \qtype_match\privacy\provider::get_metadata($collection); + $this->assertEquals($collection, $actual); + } + + public function test_export_user_preferences_no_pref() { + $this->resetAfterTest(); + + $user = $this->getDataGenerator()->create_user(); + provider::export_user_preferences($user->id); + $writer = writer::with_context(\context_system::instance()); + $this->assertFalse($writer->has_any_data()); + } + + /** + * Test the export_user_preferences given different inputs + * @dataProvider user_preference_provider + + * @param string $name The name of the user preference to get/set + * @param string $value The value stored in the database + * @param string $expected The expected transformed value + */ + public function test_export_user_preferences($name, $value, $expected) { + $this->resetAfterTest(); + $user = $this->getDataGenerator()->create_user(); + set_user_preference("qtype_match_$name", $value, $user); + provider::export_user_preferences($user->id); + $writer = writer::with_context(\context_system::instance()); + $this->assertTrue($writer->has_any_data()); + $preferences = $writer->get_user_preferences('qtype_match'); + foreach ($preferences as $key => $pref) { + $preference = get_user_preferences("qtype_match_{$key}", null, $user->id); + if ($preference === null) { + continue; + } + $desc = get_string("privacy:preference:{$key}", 'qtype_match'); + $this->assertEquals($expected, $pref->value); + $this->assertEquals($desc, $pref->description); + } + } + + /** + * Create an array of valid user preferences for the multiple choice question type. + * + * @return array Array of valid user preferences. + */ + public function user_preference_provider() { + return [ + 'default mark 1' => ['defaultmark', 1, 1], + 'penalty 33.33333%' => ['penalty', 0.3333333, '33.33333%'], + 'shuffle yes' => ['shuffleanswers', 1, 'Yes'], + 'shuffle no' => ['shuffleanswers', 0, 'No'] + ]; + } +} diff --git a/question/type/multichoice/classes/privacy/provider.php b/question/type/multichoice/classes/privacy/provider.php index 3065ef72517..8be1a51b013 100644 --- a/question/type/multichoice/classes/privacy/provider.php +++ b/question/type/multichoice/classes/privacy/provider.php @@ -24,23 +24,88 @@ namespace qtype_multichoice\privacy; +use \core_privacy\local\metadata\collection; +use \core_privacy\local\request\transform; +use \core_privacy\local\request\user_preference_provider; +use \core_privacy\local\request\writer; + defined('MOODLE_INTERNAL') || die(); /** - * Privacy Subsystem for qtype_multichoice implementing null_provider. + * Privacy Subsystem for qtype_multichoice implementing user_preference_provider. * * @copyright 2018 Andrew Nicols * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ -class provider implements \core_privacy\local\metadata\null_provider { +class provider implements + // This component has data. + // We need to return default options that have been set a user preferences. + \core_privacy\local\metadata\provider, + \core_privacy\local\request\user_preference_provider +{ /** - * Get the language string identifier with the component's language - * file to explain why this plugin stores no data. + * Returns meta data about this system. * - * @return string + * @param collection $collection The initialised collection to add items to. + * @return collection A listing of user data stored through this system. */ - public static function get_reason() : string { - return 'privacy:metadata'; + public static function get_metadata(collection $collection) : collection { + $collection->add_user_preference('qtype_multichoice_defaultmark', 'privacy:preference:defaultmark'); + $collection->add_user_preference('qtype_multichoice_penalty', 'privacy:preference:penalty'); + $collection->add_user_preference('qtype_multichoice_single', 'privacy:preference:single'); + $collection->add_user_preference('qtype_multichoice_shuffleanswers', 'privacy:preference:shuffleanswers'); + $collection->add_user_preference('qtype_multichoice_answernumbering', 'privacy:preference:answernumbering'); + $collection->add_user_preference('qtype_multichoice_showstandardinstruction', 'privacy:preference:showstandardinstruction'); + return $collection; + } + + /** + * Export all user preferences for the plugin. + * + * @param int $userid The userid of the user whose data is to be exported. + */ + public static function export_user_preferences(int $userid) { + $preference = get_user_preferences('qtype_multichoice_defaultmark', null, $userid); + if (null !== $preference) { + $desc = get_string('privacy:preference:defaultmark', 'qtype_multichoice'); + writer::export_user_preference('qtype_multichoice', 'defaultmark', $preference, $desc); + } + + $preference = get_user_preferences('qtype_multichoice_penalty', null, $userid); + if (null !== $preference) { + $desc = get_string('privacy:preference:penalty', 'qtype_multichoice'); + writer::export_user_preference('qtype_multichoice', 'penalty', transform::percentage($preference), $desc); + } + + $preference = get_user_preferences('qtype_multichoice_single', null, $userid); + if (null !== $preference) { + if ($preference) { + $stringvalue = get_string('answersingleyes', 'qtype_multichoice'); + } else { + $stringvalue = get_string('answersingleno', 'qtype_multichoice'); + } + $desc = get_string('privacy:preference:single', 'qtype_multichoice'); + writer::export_user_preference('qtype_multichoice', 'single', $stringvalue, $desc); + } + + $preference = get_user_preferences('qtype_multichoice_answernumbering', null, $userid); + if (null !== $preference) { + $desc = get_string('privacy:preference:answernumbering', 'qtype_multichoice'); + writer::export_user_preference('qtype_multichoice', 'answernumbering', + get_string('answernumbering' . $preference, 'qtype_multichoice'), $desc); + } + + $preferences = [ + 'shuffleanswers', + 'showstandardinstruction' + ]; + foreach ($preferences as $key) { + $preference = get_user_preferences("qtype_multichoice_{$key}", null, $userid); + if (null !== $preference) { + $desc = get_string("privacy:preference:{$key}", 'qtype_multichoice'); + writer::export_user_preference('qtype_multichoice', $key, transform::yesno($preference), $desc); + } + } } } diff --git a/question/type/multichoice/lang/en/qtype_multichoice.php b/question/type/multichoice/lang/en/qtype_multichoice.php index 41254f8a4ad..85df0e5e74f 100644 --- a/question/type/multichoice/lang/en/qtype_multichoice.php +++ b/question/type/multichoice/lang/en/qtype_multichoice.php @@ -65,7 +65,13 @@ $string['pluginname_link'] = 'question/type/multichoice'; $string['pluginnameadding'] = 'Adding a Multiple choice question'; $string['pluginnameediting'] = 'Editing a Multiple choice question'; $string['pluginnamesummary'] = 'Allows the selection of a single or multiple responses from a pre-defined list.'; -$string['privacy:metadata'] = 'The Multiple choice question type plugin does not store any personal data.'; +$string['privacy:metadata'] = 'Multiple choice question type plugin allows question authors to set default options as user preferences.'; +$string['privacy:preference:defaultmark'] = 'The default mark set for a given question.'; +$string['privacy:preference:penalty'] = 'The penalty for each incorrect try when questions are run using the \'Interactive with multiple tries\' or \'Adaptive mode\' behaviour.'; +$string['privacy:preference:single'] = 'Whether the answer is single with radio buttons or multiple with checkboxes.'; +$string['privacy:preference:shuffleanswers'] = 'Whether the answers should be automatically shuffled.'; +$string['privacy:preference:answernumbering'] = 'Which numbering stye should be used (1., 2., 3., .../a., b., c., ... etc.)'; +$string['privacy:preference:showstandardinstruction'] = 'Whether showing standard instruction.'; $string['selectmulti'] = 'Select one or more:'; $string['selectone'] = 'Select one:'; $string['shuffleanswers'] = 'Shuffle the choices?'; diff --git a/question/type/multichoice/tests/privacy_provider_test.php b/question/type/multichoice/tests/privacy_provider_test.php new file mode 100644 index 00000000000..fe1e265a04e --- /dev/null +++ b/question/type/multichoice/tests/privacy_provider_test.php @@ -0,0 +1,110 @@ +. + +/** + * Privacy provider tests. + * + * @package qtype_multichoice + * @copyright 2021 The Open university + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ + +use core_privacy\local\metadata\collection; +use \core_privacy\local\request\user_preference_provider; +use qtype_multichoice\privacy\provider; +use core_privacy\local\request\writer; +use core_privacy\local\request\transform; + +defined('MOODLE_INTERNAL') || die(); + +global $CFG; +require_once($CFG->dirroot . '/question/type/multichoice/classes/privacy/provider.php'); + +/** + * Privacy provider tests class. + * + * @package qtype_multichoice + * @copyright 2021 The Open university + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ +class qtype_multichoice_privacy_provider_testcase extends \core_privacy\tests\provider_testcase { + // Include the privacy helper which has assertions on it. + + public function test_get_metadata() { + $collection = new \core_privacy\local\metadata\collection('qtype_multichoice'); + $actual = \qtype_multichoice\privacy\provider::get_metadata($collection); + $this->assertEquals($collection, $actual); + } + + public function test_export_user_preferences_no_pref() { + $this->resetAfterTest(); + + $user = $this->getDataGenerator()->create_user(); + provider::export_user_preferences($user->id); + $writer = writer::with_context(\context_system::instance()); + $this->assertFalse($writer->has_any_data()); + } + + /** + * Test the export_user_preferences given different inputs + * @dataProvider user_preference_provider + + * @param string $name The name of the user preference to get/set + * @param string $value The value stored in the database + * @param string $expected The expected transformed value + */ + public function test_export_user_preferences($name, $value, $expected) { + $this->resetAfterTest(); + $user = $this->getDataGenerator()->create_user(); + set_user_preference("qtype_multichoice_$name", $value, $user); + provider::export_user_preferences($user->id); + $writer = writer::with_context(\context_system::instance()); + $this->assertTrue($writer->has_any_data()); + $preferences = $writer->get_user_preferences('qtype_multichoice'); + foreach ($preferences as $key => $pref) { + $preference = get_user_preferences("qtype_multichoice_{$key}", null, $user->id); + if ($preference === null) { + continue; + } + $desc = get_string("privacy:preference:{$key}", 'qtype_multichoice'); + $this->assertEquals($expected, $pref->value); + $this->assertEquals($desc, $pref->description); + } + } + + /** + * Create an array of valid user preferences for the multiple choice question type. + * + * @return array Array of valid user preferences. + */ + public function user_preference_provider() { + return [ + 'default mark 2' => ['defaultmark', 2, 2], + 'penalty 33.33333%' => ['penalty', 0.3333333, '33.33333%'], + 'single/multiple radio buttons' => ['single', 1, 'One answer only'], + 'single/multiple checkboxes' => ['single', 0, 'Multiple answers allowed'], + 'shuffle yes' => ['shuffleanswers', 1, 'Yes'], + 'shuffle no' => ['shuffleanswers', 0, 'No'], + 'answernumbering abc' => ['answernumbering', 'abc', 'a., b., c., ...'], + 'answernumbering ABC' => ['answernumbering', 'ABCD', 'A., B., C., ...'], + 'answernumbering 123' => ['answernumbering', '123', '1., 2., 3., ...'], + 'answernumbering iii' => ['answernumbering', 'iii', 'i., ii., iii., ...'], + 'answernumbering III' => ['answernumbering', 'IIII', 'I., II., III., ...'], + 'show standard instruction yes' => ['showstandardinstruction', 1, 'Yes'], + 'show standard instruction no' => ['showstandardinstruction', 0, 'No'] + ]; + } +} diff --git a/question/type/numerical/classes/privacy/provider.php b/question/type/numerical/classes/privacy/provider.php index 7db1dc1c9c6..8039877bad9 100644 --- a/question/type/numerical/classes/privacy/provider.php +++ b/question/type/numerical/classes/privacy/provider.php @@ -24,23 +24,113 @@ namespace qtype_numerical\privacy; +use \core_privacy\local\metadata\collection; +use \core_privacy\local\request\transform; +use \core_privacy\local\request\user_preference_provider; +use \core_privacy\local\request\writer; + defined('MOODLE_INTERNAL') || die(); /** - * Privacy Subsystem for qtype_numerical implementing null_provider. + * Privacy Subsystem for qtype_numerical implementing user_preference_provider. * * @copyright 2018 Andrew Nicols * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ -class provider implements \core_privacy\local\metadata\null_provider { +class provider implements + // This component has data. + // We need to return default options that have been set a user preferences. + \core_privacy\local\metadata\provider, + \core_privacy\local\request\user_preference_provider +{ /** - * Get the language string identifier with the component's language - * file to explain why this plugin stores no data. + * Returns meta data about this system. * - * @return string + * @param collection $collection The initialised collection to add items to. + * @return collection A listing of user data stored through this system. */ - public static function get_reason() : string { - return 'privacy:metadata'; + public static function get_metadata(collection $collection) : collection { + $collection->add_user_preference('qtype_numerical_defaultmark', 'privacy:preference:defaultmark'); + $collection->add_user_preference('qtype_numerical_penalty', 'privacy:preference:penalty'); + $collection->add_user_preference('qtype_numerical_unitrole', 'privacy:preference:unitrole'); + $collection->add_user_preference('qtype_numerical_unitpenalty', 'privacy:preference:unitpenalty'); + $collection->add_user_preference('qtype_numerical_unitgradingtypes', 'privacy:preference:unitgradingtypes'); + $collection->add_user_preference('qtype_numerical_multichoicedisplay', 'privacy:preference:multichoicedisplay'); + $collection->add_user_preference('qtype_numerical_unitsleft', 'privacy:preference:unitsleft'); + return $collection; + } + + /** + * Export all user preferences for the plugin. + * + * @param int $userid The userid of the user whose data is to be exported. + */ + public static function export_user_preferences(int $userid) { + $preference = get_user_preferences('qtype_numerical_defaultmark', null, $userid); + if (null !== $preference) { + $desc = get_string('privacy:preference:defaultmark', 'qtype_numerical'); + writer::export_user_preference('qtype_numerical', 'defaultmark', $preference, $desc); + } + + $preference = get_user_preferences('qtype_numerical_penalty', null, $userid); + if (null !== $preference) { + $desc = get_string('privacy:preference:penalty', 'qtype_numerical'); + writer::export_user_preference('qtype_numerical', 'penalty', transform::percentage($preference), $desc); + } + + $preference = get_user_preferences('qtype_numerical_unitrole', null, $userid); + if (null !== $preference) { + if ($preference == \qtype_numerical::UNITNONE) { + $stringvalue = get_string('onlynumerical', 'qtype_numerical'); + } else if ($preference == \qtype_numerical::UNITOPTIONAL) { + $stringvalue = get_string('manynumerical', 'qtype_numerical'); + } else if ($preference == \qtype_numerical::UNITGRADED) { + $stringvalue = get_string('unitgraded', 'qtype_numerical'); + } + $desc = get_string('privacy:preference:unitrole', 'qtype_numerical'); + writer::export_user_preference('qtype_numerical', 'unitrole', $stringvalue, $desc); + } + + $preference = get_user_preferences('qtype_numerical_unitpenalty', null, $userid); + if (null !== $preference) { + $desc = get_string('privacy:preference:unitpenalty', 'qtype_numerical'); + writer::export_user_preference('qtype_numerical', 'unitpenalty', $preference, $desc); + } + + $preference = get_user_preferences('qtype_numerical_unitgradingtypes', null, $userid); + if (null !== $preference) { + if ($preference == \qtype_numerical::UNITGRADEDOUTOFMARK) { + $stringvalue = get_string('decfractionofresponsegrade', 'qtype_numerical'); + } else if ($preference == \qtype_numerical::UNITGRADEDOUTOFMAX) { + $stringvalue = get_string('decfractionofquestiongrade', 'qtype_numerical'); + } + $desc = get_string('privacy:preference:unitgradingtypes', 'qtype_numerical'); + writer::export_user_preference('qtype_numerical', 'unitgradingtypes', $stringvalue, $desc); + } + + $preference = get_user_preferences('qtype_numerical_multichoicedisplay', null, $userid); + if (null !== $preference) { + if ($preference == \qtype_numerical::UNITINPUT) { + $stringvalue = get_string('editableunittext', 'qtype_numerical'); + } else if ($preference == \qtype_numerical::UNITRADIO) { + $stringvalue = get_string('unitchoice', 'qtype_numerical'); + } else if ($preference == \qtype_numerical::UNITSELECT) { + $stringvalue = get_string('unitselect', 'qtype_numerical'); + } + $desc = get_string('privacy:preference:multichoicedisplay', 'qtype_numerical'); + writer::export_user_preference('qtype_numerical', 'multichoicedisplay', $stringvalue, $desc); + } + + $preference = get_user_preferences('qtype_numerical_unitsleft', null, $userid); + if (null !== $preference) { + if ($preference) { + $stringvalue = get_string('leftexample', 'qtype_numerical'); + } else { + $stringvalue = get_string('rightexample', 'qtype_numerical'); + } + $desc = get_string('privacy:preference:unitsleft', 'qtype_numerical'); + writer::export_user_preference('qtype_numerical', 'unitsleft', $stringvalue, $desc); + } } } diff --git a/question/type/numerical/lang/en/qtype_numerical.php b/question/type/numerical/lang/en/qtype_numerical.php index 21eab957ba3..ff28d00a9b2 100644 --- a/question/type/numerical/lang/en/qtype_numerical.php +++ b/question/type/numerical/lang/en/qtype_numerical.php @@ -67,7 +67,14 @@ $string['pluginname_link'] = 'question/type/numerical'; $string['pluginnameadding'] = 'Adding a Numerical question'; $string['pluginnameediting'] = 'Editing a Numerical question'; $string['pluginnamesummary'] = 'Allows a numerical response, possibly with units, that is graded by comparing against various model answers, possibly with tolerances.'; -$string['privacy:metadata'] = 'The Numerical question type plugin does not store any personal data.'; +$string['privacy:metadata'] = 'Numerical question type plugin allows question authors to set default options as user preferences.'; +$string['privacy:preference:defaultmark'] = 'The default mark set for a given question.'; +$string['privacy:preference:penalty'] = 'The penalty for each incorrect try when questions are run using the \'Interactive with multiple tries\' or \'Adaptive mode\' behaviour.'; +$string['privacy:preference:unitrole'] = 'Whether the unit is essential, optional or not expected.'; +$string['privacy:preference:unitpenalty'] = 'What fraction (0-1) of the response grade or the question grade should apply?'; +$string['privacy:preference:unitgradingtypes'] = 'Whether unit penalty applies as a fraction (0-1) of the response grade or the question grade.'; +$string['privacy:preference:multichoicedisplay'] = 'Whether units are displayed as the text input element, multiple choice selection or a drop-down menu.'; +$string['privacy:preference:unitsleft'] = 'Whether unit displays on the left (eg. $, £) or on the right (eg. kg, km, cm).'; $string['relative'] = 'Relative'; $string['rightexample'] = 'on the right, for example 1.00cm or 1.00km'; $string['selectunits'] = 'Select units'; diff --git a/question/type/numerical/tests/privacy_provider_test.php b/question/type/numerical/tests/privacy_provider_test.php new file mode 100644 index 00000000000..0c8d9c31610 --- /dev/null +++ b/question/type/numerical/tests/privacy_provider_test.php @@ -0,0 +1,115 @@ +. + +/** + * Privacy provider tests. + * + * @package qtype_numerical + * @copyright 2021 The Open university + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ + +use core_privacy\local\metadata\collection; +use \core_privacy\local\request\user_preference_provider; +use qtype_numerical\privacy\provider; +use core_privacy\local\request\writer; +use core_privacy\local\request\transform; + +defined('MOODLE_INTERNAL') || die(); + +/** + * Privacy provider tests class. + * + * @package qtype_numerical + * @copyright 2021 The Open university + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ +class qtype_numerical_privacy_provider_testcase extends \core_privacy\tests\provider_testcase { + // Include the privacy helper which has assertions on it. + + public function test_get_metadata() { + $collection = new \core_privacy\local\metadata\collection('qtype_numerical'); + $actual = \qtype_numerical\privacy\provider::get_metadata($collection); + $this->assertEquals($collection, $actual); + } + + public function test_export_user_preferences_no_pref() { + $this->resetAfterTest(); + + $user = $this->getDataGenerator()->create_user(); + provider::export_user_preferences($user->id); + $writer = writer::with_context(\context_system::instance()); + $this->assertFalse($writer->has_any_data()); + } + + /** + * Test the export_user_preferences given different inputs + * @dataProvider user_preference_provider + + * @param string $name The name of the user preference to get/set + * @param string $value The value stored in the database + * @param string $expected The expected transformed value + */ + public function test_export_user_preferences($name, $value, $expected) { + $this->resetAfterTest(); + $user = $this->getDataGenerator()->create_user(); + set_user_preference("qtype_numerical_$name", $value, $user); + provider::export_user_preferences($user->id); + $writer = writer::with_context(\context_system::instance()); + $this->assertTrue($writer->has_any_data()); + $preferences = $writer->get_user_preferences('qtype_numerical'); + foreach ($preferences as $key => $pref) { + $preference = get_user_preferences("qtype_numerical_{$key}", null, $user->id); + if ($preference === null) { + continue; + } + $desc = get_string("privacy:preference:{$key}", 'qtype_numerical'); + $this->assertEquals($expected, $pref->value); + $this->assertEquals($desc, $pref->description); + } + } + + /** + * Create an array of valid user preferences for the multiple choice question type. + * + * @return array Array of valid user preferences. + */ + public function user_preference_provider() { + return [ + 'default mark 1.5' => ['defaultmark', 1.5, 1.5], + 'penalty 20%' => ['penalty', 0.2000000, '20%'], + 'unitrole only numerical' => ['unitrole', qtype_numerical::UNITNONE, + get_string('onlynumerical', 'qtype_numerical')], + 'unitrole many numerical' => ['unitrole', qtype_numerical::UNITOPTIONAL, + get_string('manynumerical', 'qtype_numerical')], + 'unitrole unit graded' => ['unitrole', qtype_numerical::UNITGRADED, + get_string('unitgraded', 'qtype_numerical')], + 'unit penalty 0' => ['unitpenalty', 0.01, 0.01], + 'unit grading types response grade' => ['unitgradingtypes', qtype_numerical::UNITGRADEDOUTOFMARK, + get_string('decfractionofresponsegrade', 'qtype_numerical')], + 'unit grading types question grade' => ['unitgradingtypes', qtype_numerical::UNITGRADEDOUTOFMAX, + get_string('decfractionofquestiongrade', 'qtype_numerical')], + 'multichoice display editable unit text' => ['multichoicedisplay', qtype_numerical::UNITINPUT, + get_string('editableunittext', 'qtype_numerical')], + 'multichoice display radio buttons' => ['multichoicedisplay', qtype_numerical::UNITRADIO, + get_string('unitchoice', 'qtype_numerical')], + 'multichoice display select menu' => ['multichoicedisplay', qtype_numerical::UNITSELECT, + get_string('unitselect', 'qtype_numerical')], + 'unitsleft left example' => ['unitsleft', '1', get_string('leftexample', 'qtype_numerical')], + 'unitsleft left example' => ['unitsleft', '0', get_string('rightexample', 'qtype_numerical')] + ]; + } +} diff --git a/question/type/shortanswer/classes/privacy/provider.php b/question/type/shortanswer/classes/privacy/provider.php index b86ce10bfff..27b890c0260 100644 --- a/question/type/shortanswer/classes/privacy/provider.php +++ b/question/type/shortanswer/classes/privacy/provider.php @@ -24,23 +24,65 @@ namespace qtype_shortanswer\privacy; +use core_privacy\local\metadata\collection; +use core_privacy\local\request\transform; +use core_privacy\local\request\writer; + defined('MOODLE_INTERNAL') || die(); /** - * Privacy Subsystem for qtype_shortanswer implementing null_provider. + * Privacy Subsystem for qtype_shortanswer implementing user_preference_provider. * * @copyright 2018 Andrew Nicols * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ -class provider implements \core_privacy\local\metadata\null_provider { +class provider implements + // This component has data. + // We need to return default options that have been set a user preferences. + \core_privacy\local\metadata\provider, + \core_privacy\local\request\user_preference_provider +{ /** - * Get the language string identifier with the component's language - * file to explain why this plugin stores no data. + * Returns meta data about this system. * - * @return string + * @param collection $collection The initialised collection to add items to. + * @return collection A listing of user data stored through this system. */ - public static function get_reason() : string { - return 'privacy:metadata'; + public static function get_metadata(collection $collection) : collection { + $collection->add_user_preference('qtype_shortanswer_defaultmark', 'privacy:preference:defaultmark'); + $collection->add_user_preference('qtype_shortanswer_penalty', 'privacy:preference:penalty'); + $collection->add_user_preference('qtype_shortanswer_usecase', 'privacy:preference:usecase'); + return $collection; + } + + /** + * Export all user preferences for the plugin. + * + * @param int $userid The userid of the user whose data is to be exported. + */ + public static function export_user_preferences(int $userid) { + $preference = get_user_preferences('qtype_shortanswer_defaultmark', null, $userid); + if (null !== $preference) { + $desc = get_string('privacy:preference:defaultmark', 'qtype_shortanswer'); + writer::export_user_preference('qtype_shortanswer', 'defaultmark', $preference, $desc); + } + + $preference = get_user_preferences('qtype_shortanswer_penalty', null, $userid); + if (null !== $preference) { + $desc = get_string('privacy:preference:penalty', 'qtype_shortanswer'); + writer::export_user_preference('qtype_shortanswer', 'penalty', transform::percentage($preference), $desc); + } + + $preference = get_user_preferences('qtype_shortanswer_usecase', null, $userid); + if (null !== $preference) { + $desc = get_string('privacy:preference:usecase', 'qtype_shortanswer'); + if ($preference) { + $strvalue = get_string('caseyes', 'qtype_shortanswer'); + } else { + $strvalue = get_string('caseno', 'qtype_shortanswer'); + } + writer::export_user_preference('qtype_shortanswer', 'shuffleanswers', $strvalue, $desc); + } } } diff --git a/question/type/shortanswer/lang/en/qtype_shortanswer.php b/question/type/shortanswer/lang/en/qtype_shortanswer.php index 9546fec410d..2b5c96314bb 100644 --- a/question/type/shortanswer/lang/en/qtype_shortanswer.php +++ b/question/type/shortanswer/lang/en/qtype_shortanswer.php @@ -41,4 +41,7 @@ $string['pluginname_link'] = 'question/type/shortanswer'; $string['pluginnameadding'] = 'Adding a short answer question'; $string['pluginnameediting'] = 'Editing a Short answer question'; $string['pluginnamesummary'] = 'Allows a response of one or a few words that is graded by comparing against various model answers, which may contain wildcards.'; -$string['privacy:metadata'] = 'The Short answer question type plugin does not store any personal data.'; +$string['privacy:metadata'] = 'Short answer question type plugin allows question authors to set default options as user preferences.'; +$string['privacy:preference:defaultmark'] = 'The default mark set for a given question.'; +$string['privacy:preference:penalty'] = 'The penalty for each incorrect try when questions are run using the \'Interactive with multiple tries\' or \'Adaptive mode\' behaviour.'; +$string['privacy:preference:usecase'] = 'Whether the answers should be case sensitive.'; diff --git a/question/type/shortanswer/tests/privacy_provider_test.php b/question/type/shortanswer/tests/privacy_provider_test.php new file mode 100644 index 00000000000..6ae688fd82c --- /dev/null +++ b/question/type/shortanswer/tests/privacy_provider_test.php @@ -0,0 +1,101 @@ +. + +/** + * Privacy provider tests. + * + * @package qtype_shortanswer + * @copyright 2021 The Open university + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ + +use core_privacy\local\metadata\collection; +use \core_privacy\local\request\user_preference_provider; +use qtype_shortanswer\privacy\provider; +use core_privacy\local\request\writer; +use core_privacy\local\request\transform; + +defined('MOODLE_INTERNAL') || die(); + +global $CFG; +require_once($CFG->dirroot . '/question/type/shortanswer/classes/privacy/provider.php'); + +/** + * Privacy provider tests class. + * + * @package qtype_shortanswer + * @copyright 2021 The Open university + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ +class qtype_shortanswer_privacy_provider_testcase extends \core_privacy\tests\provider_testcase { + // Include the privacy helper which has assertions on it. + + public function test_get_metadata() { + $collection = new \core_privacy\local\metadata\collection('qtype_shortanswer'); + $actual = \qtype_shortanswer\privacy\provider::get_metadata($collection); + $this->assertEquals($collection, $actual); + } + + public function test_export_user_preferences_no_pref() { + $this->resetAfterTest(); + + $user = $this->getDataGenerator()->create_user(); + provider::export_user_preferences($user->id); + $writer = writer::with_context(\context_system::instance()); + $this->assertFalse($writer->has_any_data()); + } + + /** + * Test the export_user_preferences given different inputs + * @dataProvider user_preference_provider + + * @param string $name The name of the user preference to get/set + * @param string $value The value stored in the database + * @param string $expected The expected transformed value + */ + public function test_export_user_preferences($name, $value, $expected) { + $this->resetAfterTest(); + $user = $this->getDataGenerator()->create_user(); + set_user_preference("qtype_shortanswer_$name", $value, $user); + provider::export_user_preferences($user->id); + $writer = writer::with_context(\context_system::instance()); + $this->assertTrue($writer->has_any_data()); + $preferences = $writer->get_user_preferences('qtype_shortanswer'); + foreach ($preferences as $key => $pref) { + $preference = get_user_preferences("qtype_shortanswer_{$key}", null, $user->id); + if ($preference === null) { + continue; + } + $desc = get_string("privacy:preference:{$key}", 'qtype_shortanswer'); + $this->assertEquals($expected, $pref->value); + $this->assertEquals($desc, $pref->description); + } + } + + /** + * Create an array of valid user preferences for the multiple choice question type. + * + * @return array Array of valid user preferences. + */ + public function user_preference_provider() { + return [ + 'default mark 2' => ['defaultmark', 2, 2], + 'penalty 33.33333%' => ['penalty', 0.3333333, '33.33333%'], + 'usecase yes' => ['usecase', 1, 'Yes, case must match'], + 'usecase no' => ['usecase', 0, 'No, case is unimportant'] + ]; + } +}