Skip to content

Commit

Permalink
MDL-71258 questions: privacy support for settings defaults preferences
Browse files Browse the repository at this point in the history
  • Loading branch information
Mahmoud Kassaei authored and timhunt committed Apr 30, 2021
1 parent a5f0b35 commit 9578201
Show file tree
Hide file tree
Showing 28 changed files with 1,587 additions and 72 deletions.
14 changes: 14 additions & 0 deletions privacy/classes/local/request/transform.php
Expand Up @@ -80,4 +80,18 @@ public static function yesno($value) {
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;
}
}
}
51 changes: 44 additions & 7 deletions question/type/ddimageortext/classes/privacy/provider.php
Expand Up @@ -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 <andrew@nicols.co.uk>
* @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
{

/**
* Returns meta data about this system.
*
* @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_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;
}

/**
* Get the language string identifier with the component's language
* file to explain why this plugin stores no data.
* Export all user preferences for the plugin.
*
* @return string
* @param int $userid The userid of the user whose data is to be exported.
*/
public static function get_reason() : string {
return 'privacy:metadata';
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);
}
}
}
5 changes: 4 additions & 1 deletion question/type/ddimageortext/lang/en/qtype_ddimageortext.php
Expand Up @@ -63,7 +63,10 @@
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}';
Expand Down
101 changes: 101 additions & 0 deletions question/type/ddimageortext/tests/privacy_provider_test.php
@@ -0,0 +1,101 @@
<?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/>.

/**
* 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']
];
}
}
51 changes: 44 additions & 7 deletions question/type/ddmarker/classes/privacy/provider.php
Expand Up @@ -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 <andrew@nicols.co.uk>
* @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
{

/**
* Returns meta data about this system.
*
* @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_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;
}

/**
* Get the language string identifier with the component's language
* file to explain why this plugin stores no data.
* Export all user preferences for the plugin.
*
* @return string
* @param int $userid The userid of the user whose data is to be exported.
*/
public static function get_reason() : string {
return 'privacy:metadata';
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);
}
}
}
5 changes: 4 additions & 1 deletion question/type/ddmarker/lang/en/qtype_ddmarker.php
Expand Up @@ -81,7 +81,10 @@
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';
Expand Down
101 changes: 101 additions & 0 deletions question/type/ddmarker/tests/privacy_provider_test.php
@@ -0,0 +1,101 @@
<?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/>.

/**
* 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']
];
}
}

0 comments on commit 9578201

Please sign in to comment.