--- /dev/null
+<?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/>.
+
+/**
+ * Class containing helper methods for processing data requests.
+ *
+ * @package tool_dataprivacy
+ * @copyright 2018 Adrian Greeve
+ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+namespace tool_dataprivacy;
+
+defined('MOODLE_INTERNAL') || die();
+
+/**
+ * Class containing helper methods for processing data requests.
+ *
+ * @copyright 2018 Adrian Greeve
+ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+class metadata_registry {
+
+ /**
+ * Returns plugin types / plugins and the user data that it stores in a format that can be sent to a template.
+ *
+ * @return array An array with all of the plugin types / plugins and the user data they store.
+ */
+ public function get_registry_metadata() {
+ $manager = new \core_privacy\manager();
+ $pluginman = \core_plugin_manager::instance();
+ $contributedplugins = $this->get_contrib_list();
+ $metadata = $manager->get_metadata_for_components();
+ $fullyrichtree = $this->get_full_component_list();
+ foreach ($fullyrichtree as $branch => $leaves) {
+ $plugintype = $leaves['plugin_type'];
+ $plugins = array_map(function($component) use ($manager, $metadata, $contributedplugins, $plugintype, $pluginman) {
+ // Use the plugin name for the plugins, ignore for core subsystems.
+ $internaldata = ($plugintype == 'core') ? ['component' => $component] :
+ ['component' => $pluginman->plugin_name($component)];
+ $internaldata['raw_component'] = $component;
+ if ($manager->component_is_compliant($component)) {
+ $internaldata['compliant'] = true;
+ if (isset($metadata[$component])) {
+ $collection = $metadata[$component]->get_collection();
+ $internaldata = $this->format_metadata($collection, $component, $internaldata);
+ } else {
+ // Call get_reason for null provider.
+ $internaldata['nullprovider'] = get_string($manager->get_null_provider_reason($component), $component);
+ }
+ } else {
+ $internaldata['compliant'] = false;
+ }
+ // Check to see if we are an external plugin.
+ $componentshortname = explode('_', $component);
+ $shortname = array_pop($componentshortname);
+ if (isset($contributedplugins[$plugintype][$shortname])) {
+ $internaldata['external'] = true;
+ }
+ return $internaldata;
+ }, $leaves['plugins']);
+ $fullyrichtree[$branch]['plugin_type_raw'] = $plugintype;
+ // We're done using the plugin type. Convert it to a readable string.
+ $fullyrichtree[$branch]['plugin_type'] = $pluginman->plugintype_name($plugintype);
+ $fullyrichtree[$branch]['plugins'] = $plugins;
+ }
+ return $fullyrichtree;
+ }
+
+ /**
+ * Formats the metadata for use with a template.
+ *
+ * @param array $collection The collection associated with the component that we want to expand and format.
+ * @param string $component The component that we are dealing in
+ * @param array $internaldata The array to add the formatted metadata to.
+ * @return array The internal data array with the formatted metadata.
+ */
+ protected function format_metadata($collection, $component, $internaldata) {
+ foreach ($collection as $collectioninfo) {
+ $privacyfields = $collectioninfo->get_privacy_fields();
+ $fields = '';
+ if (!empty($privacyfields)) {
+ $fields = array_map(function($key, $field) use ($component) {
+ return [
+ 'field_name' => $key,
+ 'field_summary' => get_string($field, $component)
+ ];
+ }, array_keys($privacyfields), $privacyfields);
+ }
+ // Can the metadata types be located somewhere else besides core?
+ $items = explode('\\', get_class($collectioninfo));
+ $type = array_pop($items);
+ $typedata = [
+ 'name' => $collectioninfo->get_name(),
+ 'type' => $type,
+ 'fields' => $fields,
+ 'summary' => get_string($collectioninfo->get_summary(), $component)
+ ];
+ if (strpos($type, 'subsystem_link') === 0 || strpos($type, 'plugintype_link') === 0) {
+ $typedata['link'] = true;
+ }
+ $internaldata['metadata'][] = $typedata;
+ }
+ return $internaldata;
+ }
+
+ /**
+ * Return the full list of components.
+ *
+ * @return array An array of plugin types which contain plugin data.
+ */
+ protected function get_full_component_list() {
+ $list = \core_component::get_component_list();
+ $formattedlist = [];
+ foreach ($list as $plugintype => $plugin) {
+ $formattedlist[] = ['plugin_type' => $plugintype, 'plugins' => array_keys($plugin)];
+ }
+ return $formattedlist;
+ }
+
+ /**
+ * Returns a list of contributed plugins installed on the system.
+ *
+ * @return array A list of contributed plugins installed.
+ */
+ protected function get_contrib_list() {
+ return array_map(function($plugins) {
+ return array_filter($plugins, function($plugindata) {
+ return !$plugindata->is_standard();
+ });
+ }, \core_plugin_manager::instance()->get_plugins());
+ }
+}
--- /dev/null
+<?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/>.
+
+/**
+ * Data registry renderable.
+ *
+ * @package tool_dataprivacy
+ * @copyright 2018 David Monllao
+ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+namespace tool_dataprivacy\output;
+defined('MOODLE_INTERNAL') || die();
+
+use renderable;
+use renderer_base;
+use stdClass;
+use templatable;
+
+require_once($CFG->libdir . '/coursecatlib.php');
+require_once($CFG->dirroot . '/' . $CFG->admin . '/tool/dataprivacy/lib.php');
+require_once($CFG->libdir . '/blocklib.php');
+
+/**
+ * Class containing the data registry compliance renderable
+ *
+ * @copyright 2018 Adrian Greeve
+ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+class data_registry_compliance_page implements renderable, templatable {
+
+ protected $metadata;
+
+ /**
+ * Constructor.
+ */
+ public function __construct($metadata) {
+ $this->metadata = $metadata;
+ }
+
+ /**
+ * Export this data so it can be used as the context for a mustache template.
+ *
+ * @param renderer_base $output
+ * @return stdClass
+ */
+ public function export_for_template(renderer_base $output) {
+ global $PAGE;
+
+ $data = ['types' => $this->metadata];
+ // print_object($data);
+
+ return $data;
+ }
+
+
+}
return parent::render_from_template('tool_dataprivacy/data_registry', $data);
}
+ /**
+ * Render the data compliance registry.
+ *
+ * @param data_registry_page $page
+ * @return string html for the page
+ * @throws moodle_exception
+ */
+ public function render_data_registry_compliance_page(data_registry_compliance_page $page) {
+ $data = $page->export_for_template($this);
+ return parent::render_from_template('tool_dataprivacy/data_registry_compliance', $data);
+ }
+
/**
* Render the purposes management page.
*
--- /dev/null
+<?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/>.
+
+/**
+ * Prints the compliance data registry main page.
+ *
+ * @copyright 2018 onwards Adrian Greeve <adriangreeve.com>
+ * @license http://www.gnu.org/copyleft/gpl.html GNU Public License
+ * @package tool_dataprivacy
+ */
+
+require_once(__DIR__ . '/../../../config.php');
+require_once($CFG->dirroot . '/' . $CFG->admin . '/tool/dataprivacy/lib.php');
+
+$contextlevel = optional_param('contextlevel', CONTEXT_SYSTEM, PARAM_INT);
+$contextid = optional_param('contextid', 0, PARAM_INT);
+
+$url = new moodle_url('/admin/tool/dataprivacy/dataregistry2.php');
+$title = get_string('dataregistry2', 'tool_dataprivacy');
+
+\tool_dataprivacy\page_helper::setup($url, $title);
+
+$output = $PAGE->get_renderer('tool_dataprivacy');
+echo $output->header();
+
+// Get data!
+$metadatatool = new \tool_dataprivacy\metadata_registry();
+$metadata = $metadatatool->get_registry_metadata();
+
+$dataregistry = new tool_dataprivacy\output\data_registry_compliance_page($metadata);
+
+echo $output->render($dataregistry);
+echo $OUTPUT->footer();
$string['categorieslist'] = 'List of data categories';
$string['categoryupdated'] = 'Category updated';
$string['close'] = 'Close';
+$string['compliant'] = 'Compliant';
$string['confirmapproval'] = 'Do you really want to approve this data request?';
$string['confirmcontextdeletion'] = 'Do you really want to confirm the deletion of the selected contexts? This will also delete all of the user data for their respective sub-contexts.';
$string['confirmdenial'] = 'Do you really want deny this data request?';
$string['dataprivacy:makedatarequestsforchildren'] = 'Make data requests for children';
$string['dataprivacy:managedatarequests'] = 'Manage data requests';
$string['dataprivacy:managedataregistry'] = 'Manage data registry';
+$string['dataprivacysettings'] = 'Data privacy settings';
$string['dataregistry'] = 'Data registry';
+$string['dataregistry2'] = 'Plugin privacy registry';
+$string['dataregistrysetup'] = 'Settings';
$string['datarequestemailsubject'] = 'Data request: {$a}';
$string['datarequests'] = 'Data requests';
$string['daterequested'] = 'Date requested';
$string['expiredretentionperiodtask'] = 'Expired retention period';
$string['expiry'] = 'Expiry';
$string['frontpagecourse'] = 'Front page course';
+$string['expandplugin'] = 'Expand and collapse plugin.';
+$string['expandplugintype'] = 'Expand and collapse plugin type.';
+$string['explanationtitle'] = 'Icons used on this page and what they mean.';
+$string['external'] = 'External';
+$string['externalexplanation'] = 'An additional plugin installed on this site.';
+$string['hide'] = 'Collapse all';
$string['inherit'] = 'Inherit';
$string['messageprovider:contactdataprotectionofficer'] = 'Data requests';
$string['messageprovider:datarequestprocessingresults'] = 'Data request processing results';
$string['nosubjectaccessrequests'] = 'There are no data requests that you need to act on';
$string['nosystemdefaults'] = 'Site purpose and category have not yet been defined.';
$string['notset'] = 'Not set (use the default value)';
+$string['pluginregistrytitle'] = 'Plugin privacy compliance registry';
$string['privacy'] = 'Privacy';
$string['privacy:metadata:request'] = 'Information from personal data requests (subject access and deletion requests) made for this site.';
$string['privacy:metadata:request:comments'] = 'Any user comments accompanying the request.';
$string['requesttypeexportshort'] = 'Export';
$string['requesttypeothers'] = 'General inquiry';
$string['requesttypeothersshort'] = 'Others';
+$string['requiresattention'] = 'Requires attention.';
+$string['requiresattentionexplanation'] = 'This plugin does not implement the Moodle privacy API. If this plugin stores any personal data it will not be able to be exported or deleted through Moodle\'s privacy system.';
$string['resultdeleted'] = 'You recently requested to have your account and personal data in {$a} to be deleted. This process has been completed and you will no longer be able to log in.';
$string['resultdownloadready'] = 'Your copy of your personal data in {$a} that you recently requested is now available for download. Please click on the link below to go to the download page.';
$string['reviewdata'] = 'Review data';
$string['subjectscope'] = 'Subject scope';
$string['user'] = 'User';
$string['viewrequest'] = 'View the request';
+$string['visible'] = 'Expand all';
// Link that leads to the review page of expired contexts that are up for deletion.
$ADMIN->add('privacy', new admin_externalpage('datadeletion', get_string('datadeletion', 'tool_dataprivacy'),
new moodle_url('/admin/tool/dataprivacy/datadeletion.php'), 'tool/dataprivacy:managedataregistry')
+
+// Link that leads to the other data registry management page.
+$ADMIN->add('dataprivacysettings', new admin_externalpage('dataregistry2', get_string('dataregistry2', 'tool_dataprivacy'),
+ new moodle_url('/admin/tool/dataprivacy/dataregistry2.php'), 'tool/dataprivacy:managedataregistry')
);
--- /dev/null
+{{!
+ 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 comments.
+
+ You should have received a copy of the GNU General Public License
+ along with Moodle. If not, see <http://www.gnu.org/licenses/>.
+}}
+{{!
+ @template tool_dataprivacy/component_status
+
+ Data registry main page.
+
+ Classes required for JS:
+ * none
+
+ Data attributes required for JS:
+ * none
+
+ Context variables required for this template:
+ * none
+
+ Example context (json):
+ {
+ "compliant" : "True",
+ "raw_component" : "core_comment",
+ "component" : "Core comment",
+ "external" : "True",
+ "metadata" : {
+ "name" : "comments",
+ "type" : "database_table",
+ "summary" : "Stores comments of users",
+ "fields" : {
+ "field_name" : "content",
+ "field_summary" : "Stores the text of the content."
+ }
+ }
+ }
+}}
+
+<div class="row">
+ <div class="col">
+ {{#compliant}}
+ <a class="expand" data-component="{{raw_component}}" href='#'>
+ <h4 class="d-inline p-r-1 p-l-1" id="{{raw_component}}">{{#pix}}t/collapsed, moodle, {{#str}}expandplugin, tool_dataprivacy{{/str}}{{/pix}}{{component}}</h4>
+ </a>
+ <!-- <span class="badge badge-pill badge-success">{{#str}}compliant, tool_dataprivacy{{/str}}</span> -->
+ {{/compliant}}
+ {{^compliant}}
+ <h4 class="d-inline p-r-1 p-l-1" id="{{raw_component}}">{{component}}</h4>
+ <span>{{#pix}}i/risk_xss, moodle, {{#str}}requiresattention, tool_dataprivacy{{/str}}{{/pix}}</span>
+ {{/compliant}}
+ {{#external}}
+ <span class="badge badge-pill badge-notice">{{#str}}external, tool_dataprivacy{{/str}}</span>
+ {{/external}}
+ </div>
+</div>
+
+ {{#compliant}}
+ <div class="hide" data-section="{{raw_component}}" aria-expanded="false">
+ {{#metadata}}
+ <hr />
+ <div class="row-fluid">
+ <div class="span2 col-xs-3">
+ {{#link}}
+ <a href="#{{name}}"><h5>{{name}}</h5></a>
+ {{/link}}
+ {{^link}}
+ <h5>{{name}}</h5>
+ {{/link}}
+ <div class="p-b-1 small text-muted">{{type}}</div>
+ </div>
+ <div class="span10 col-xs-9">{{summary}}</div>
+ </div>
+ <table class="table table-sm">
+ <tbody>
+ {{#fields}}
+ <tr class="row">
+ <td class="col-xs-3">{{field_name}}</td>
+ <td class="col-xs-9">{{field_summary}}</td>
+ </tr>
+ {{/fields}}
+ </tbody>
+ </table>
+ {{/metadata}}
+ {{#nullprovider}}
+ <hr />
+ <div>{{nullprovider}}</div>
+ {{/nullprovider}}
+ </div>
+ {{/compliant}}
+<hr />
+
+
+{{#js}}
+require(['jquery', 'core/url'], function($, url) {
+
+ var expandedImage = $('<img alt="" src="' + url.imageUrl('t/expanded') + '"/>');
+ var collapsedImage = $('<img alt="" src="' + url.imageUrl('t/collapsed') + '"/>');
+
+ $('.expand').click(function(e) {
+ e.preventDefault();
+ e.stopPropagation();
+ e.stopImmediatePropagation();
+ var component = $(this).data('component');
+ var metadata = $('[data-section=\'' + component + '\']');
+ var metainfo = metadata.attr('class');
+ if (metadata.attr('class') === 'hide') {
+ metadata.attr('class', 'visible');
+ $(this).children('img').attr('src', expandedImage.attr('src'));
+ metadata.attr('aria-expanded', true);
+ } else {
+ metadata.attr('class', 'hide');
+ $(this).children('img').attr('src', collapsedImage.attr('src'));
+ metadata.attr('aria-expanded', false);
+ }
+ });
+});
+{{/js}}
--- /dev/null
+{{!
+ 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 comments.
+
+ You should have received a copy of the GNU General Public License
+ along with Moodle. If not, see <http://www.gnu.org/licenses/>.
+}}
+{{!
+ @template tool_dataprivacy/data_registry_compliance
+
+ Data registry main page.
+
+ Classes required for JS:
+ * none
+
+ Data attributes required for JS:
+ * none
+
+ Context variables required for this template:
+ * none
+
+ Example context (json):
+ {
+ "types" : {
+ "plugin_type_raw" : "mod",
+ "plugin_type" : "Activities and Modules"
+ }
+ }
+}}
+<div>
+ <h2>{{#str}}pluginregistrytitle, tool_dataprivacy{{/str}}</h2>
+ <hr />
+ <p><strong>{{#str}}explanationtitle, tool_dataprivacy{{/str}}</strong></p>
+ <dl>
+ <dt>{{#pix}}i/risk_xss, moodle, {{#str}}requiresattention, tool_dataprivacy{{/str}}{{/pix}}</dt>
+ <dd>{{#str}}requiresattentionexplanation, tool_dataprivacy{{/str}}</dd>
+ <dt><span class="badge badge-pill badge-notice">{{#str}}external, tool_dataprivacy{{/str}}</span></dt>
+ <dd>{{#str}}externalexplanation, tool_dataprivacy{{/str}}</dd>
+ </dl>
+ <hr />
+ <div><a class="tool_dataprivacy-expand-all pull-right" href="#" data-visibility-state='visible'>{{#str}}visible, tool_dataprivacy{{/str}}</a></div>
+ {{#types}}
+ <div class="container-fluid">
+ <div class="row">
+ <div class="col">
+ <a class="other-expand" href='#' data-plugin="{{plugin_type_raw}}">
+ <h3 id="{{plugin_type_raw}}">{{#pix}}t/collapsed, moodle, {{#str}}expandplugintype, tool_dataprivacy{{/str}}{{/pix}}{{plugin_type}}</h3>
+ </a>
+ </div>
+ </div>
+ <div class="hide" data-plugintarget="{{plugin_type_raw}}" aria-expanded="false">
+ {{#plugins}}
+ {{> tool_dataprivacy/component_status}}
+ {{/plugins}}
+ </div>
+ </div>
+ {{/types}}
+</div>
+{{#js}}
+require(['jquery', 'core/url', 'core/str'], function($, url, str) {
+
+ var expandedImage = $('<img alt="" src="' + url.imageUrl('t/expanded') + '"/>');
+ var collapsedImage = $('<img alt="" src="' + url.imageUrl('t/collapsed') + '"/>');
+
+ $('.other-expand').click(function(e) {
+ e.preventDefault();
+ e.stopPropagation();
+ e.stopImmediatePropagation();
+ window.console.log(this);
+ var plugin = $(this).data('plugin');
+ var metadata = $('[data-plugintarget=\'' + plugin + '\']');
+ if (metadata.attr('class') === 'hide') {
+ metadata.attr('class', 'visible');
+ $(this).children('img').attr('src', expandedImage.attr('src'));
+ metadata.attr('aria-expanded', true);
+ } else {
+ metadata.attr('class', 'hide');
+ $(this).children('img').attr('src', collapsedImage.attr('src'));
+ metadata.attr('aria-expanded', false);
+ }
+ });
+
+ $('.tool_dataprivacy-expand-all').click(function(e) {
+ e.preventDefault();
+ e.stopPropagation();
+ var nextstate = $(this).data('visibilityState');
+ var currentstate = (nextstate == 'visible') ? 'hide' : 'visible';
+ var ariaexpandedstate = (nextstate == 'visible') ? true : false;
+ $('.' + currentstate).each(function() {
+ $(this).attr('class', nextstate);
+ $(this).attr('aria-expanded', ariaexpandedstate);
+ });
+ $(this).data('visibilityState', currentstate);
+
+ str.get_string(currentstate, 'tool_dataprivacy').then(function(langString) {
+ var visibilitynode = $('.tool_dataprivacy-expand-all');
+ visibilitynode.html(langString);
+ }).catch(Notification.exception);
+ });
+});
+{{/js}}
--- /dev/null
+<?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/>.
+
+/**
+ * Metadata registry tests.
+ *
+ * @package tool_dataprivacy
+ * @copyright 2018 Adrian Greeve <adriangreeve.com>
+ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+
+defined('MOODLE_INTERNAL') || die();
+global $CFG;
+
+/**
+ * Metadata registry tests.
+ *
+ * @package tool_dataprivacy
+ * @copyright 2018 Adrian Greeve <adriangreeve.com>
+ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+class tool_dataprivacy_metadata_registry_testcase extends advanced_testcase {
+
+ /**
+ * Fetch the meta data and return it in a form that we can easily unit test.
+ *
+ * @return array the meta data.
+ */
+ protected function get_meta_data() {
+ $metadataregistry = new \tool_dataprivacy\metadata_registry();
+ $data = $metadataregistry->get_registry_metadata();
+ $newdata = [];
+ foreach ($data as $value) {
+ $additional = [];
+ foreach ($value['plugins'] as $moredata) {
+ $additional[$moredata['raw_component']] = $moredata;
+ }
+ $newdata[$value['plugin_type_raw']] = $additional;
+ }
+ return $newdata;
+ }
+
+ /**
+ * Test that we can fetch metadata about users for the whole system and that it matches the system count.
+ */
+ public function test_get_registry_metadata_count() {
+ $data = $this->get_meta_data();
+
+ $plugintypes = \core_component::get_plugin_types();
+
+ // Check that we have the correct number of plugin types.
+ $plugincount = count($plugintypes) + 1; // Plus one for core.
+ $this->assertEquals($plugincount, count($data));
+
+ // Check that each plugin count matches.
+ foreach ($plugintypes as $plugintype => $notused) {
+ $plugins = \core_component::get_plugin_list($plugintype);
+ $this->assertEquals(count($plugins), count($data[$plugintype]));
+ }
+
+ // Let's check core subsystems.
+ $coresubsystems = \core_component::get_core_subsystems();
+ $this->assertEquals(count($coresubsystems), count($data['core']));
+ }
+
+ /**
+ * Check that the expected null provider information is returned.
+ */
+ public function test_get_registry_metadata_null_provider_details() {
+ $data = $this->get_meta_data();
+
+ // Check details of core privacy (a null privder) are correct.
+ $coreprivacy = $data['core']['core_privacy'];
+ $this->assertEquals(1, $coreprivacy['compliant']);
+ $this->assertNotEmpty($coreprivacy['nullprovider']);
+ }
+
+ /**
+ * Check that the expected privacy provider information is returned.
+ */
+ public function test_get_registry_metadata_provider_details() {
+ $data = $this->get_meta_data();
+
+ // Check details of core rating (a normal provider) are correct.
+ $corerating = $data['core']['core_rating'];
+ $this->assertEquals(1, $corerating['compliant']);
+ $this->assertNotEmpty($corerating['metadata']);
+ $this->assertEquals('database_table', $corerating['metadata'][0]['type']);
+ $this->assertNotEmpty('database_table', $corerating['metadata'][0]['fields']);
+ }
+}