1 <?php 2 // This file is part of Moodle - http://moodle.org/ 3 // 4 // Moodle is free software: you can redistribute it and/or modify 5 // it under the terms of the GNU General Public License as published by 6 // the Free Software Foundation, either version 3 of the License, or 7 // (at your option) any later version. 8 // 9 // Moodle is distributed in the hope that it will be useful, 10 // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 // GNU General Public License for more details. 13 // 14 // You should have received a copy of the GNU General Public License 15 // along with Moodle. If not, see <http://www.gnu.org/licenses/>. 16 17 /** 18 * Class provider_test 19 * 20 * @package core_customfield 21 * @copyright 2019 Marina Glancy 22 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 23 */ 24 namespace core_customfield\privacy; 25 26 defined('MOODLE_INTERNAL') || die(); 27 28 use core_privacy\tests\provider_testcase; 29 use core_privacy\local\request\approved_contextlist; 30 use core_privacy\local\request\writer; 31 use core_customfield\privacy\provider; 32 33 /** 34 * Class provider_test 35 * 36 * @package core_customfield 37 * @copyright 2019 Marina Glancy 38 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 39 */ 40 class provider_test extends provider_testcase { 41 42 /** 43 * Generate data. 44 * 45 * @return array 46 */ 47 protected function generate_test_data(): array { 48 $this->resetAfterTest(); 49 50 $generator = $this->getDataGenerator()->get_plugin_generator('core_customfield'); 51 $cfcats[1] = $generator->create_category(); 52 $cfcats[2] = $generator->create_category(); 53 $cffields[11] = $generator->create_field( 54 ['categoryid' => $cfcats[1]->get('id'), 'type' => 'checkbox']); 55 $cffields[12] = $generator->create_field( 56 ['categoryid' => $cfcats[1]->get('id'), 'type' => 'date']); 57 $cffields[13] = $generator->create_field( 58 ['categoryid' => $cfcats[1]->get('id'), 59 'type' => 'select', 'configdata' => ['options' => "a\nb\nc"]]); 60 $cffields[14] = $generator->create_field( 61 ['categoryid' => $cfcats[1]->get('id'), 'type' => 'text']); 62 $cffields[15] = $generator->create_field( 63 ['categoryid' => $cfcats[1]->get('id'), 'type' => 'textarea']); 64 $cffields[21] = $generator->create_field( 65 ['categoryid' => $cfcats[2]->get('id')]); 66 $cffields[22] = $generator->create_field( 67 ['categoryid' => $cfcats[2]->get('id')]); 68 69 $courses[1] = $this->getDataGenerator()->create_course(); 70 $courses[2] = $this->getDataGenerator()->create_course(); 71 $courses[3] = $this->getDataGenerator()->create_course(); 72 73 $generator->add_instance_data($cffields[11], $courses[1]->id, 1); 74 $generator->add_instance_data($cffields[12], $courses[1]->id, 1546300800); 75 $generator->add_instance_data($cffields[13], $courses[1]->id, 2); 76 $generator->add_instance_data($cffields[14], $courses[1]->id, 'Hello1'); 77 $generator->add_instance_data($cffields[15], $courses[1]->id, 78 ['text' => '<p>Hi there</p>', 'format' => FORMAT_HTML]); 79 80 $generator->add_instance_data($cffields[21], $courses[1]->id, 'hihi1'); 81 82 $generator->add_instance_data($cffields[14], $courses[2]->id, 'Hello2'); 83 84 $generator->add_instance_data($cffields[21], $courses[2]->id, 'hihi2'); 85 86 $user = $this->getDataGenerator()->create_user(); 87 $this->setUser($user); 88 89 return [ 90 'user' => $user, 91 'cfcats' => $cfcats, 92 'cffields' => $cffields, 93 'courses' => $courses, 94 ]; 95 } 96 97 /** 98 * Test for provider::get_metadata() 99 */ 100 public function test_get_metadata() { 101 $collection = new \core_privacy\local\metadata\collection('core_customfield'); 102 $collection = provider::get_metadata($collection); 103 $this->assertNotEmpty($collection); 104 } 105 106 /** 107 * Test for provider::get_customfields_data_contexts 108 */ 109 public function test_get_customfields_data_contexts() { 110 global $DB; 111 [ 112 'cffields' => $cffields, 113 'cfcats' => $cfcats, 114 'courses' => $courses, 115 ] = $this->generate_test_data(); 116 117 list($sql, $params) = $DB->get_in_or_equal([$courses[1]->id, $courses[2]->id], SQL_PARAMS_NAMED); 118 $r = provider::get_customfields_data_contexts('core_course', 'course', '=0', 119 $sql, $params); 120 $this->assertEqualsCanonicalizing([\context_course::instance($courses[1]->id)->id, 121 \context_course::instance($courses[2]->id)->id], 122 $r->get_contextids()); 123 } 124 125 /** 126 * Test for provider::get_customfields_configuration_contexts() 127 */ 128 public function test_get_customfields_configuration_contexts() { 129 $this->generate_test_data(); 130 131 $r = provider::get_customfields_configuration_contexts('core_course', 'course'); 132 $this->assertEquals([\context_system::instance()->id], $r->get_contextids()); 133 } 134 135 /** 136 * Test for provider::export_customfields_data() 137 */ 138 public function test_export_customfields_data() { 139 global $USER, $DB; 140 $this->resetAfterTest(); 141 [ 142 'cffields' => $cffields, 143 'cfcats' => $cfcats, 144 'courses' => $courses, 145 ] = $this->generate_test_data(); 146 147 // Hack one of the fields so it has an invalid field type. 148 $invalidfieldid = $cffields[21]->get('id'); 149 $DB->update_record('customfield_field', ['id' => $invalidfieldid, 'type' => 'invalid']); 150 151 $context = \context_course::instance($courses[1]->id); 152 $contextlist = new approved_contextlist($USER, 'core_customfield', [$context->id]); 153 provider::export_customfields_data($contextlist, 'core_course', 'course', '=0', '=:i', ['i' => $courses[1]->id]); 154 /** @var core_privacy\tests\request\content_writer $writer */ 155 $writer = writer::with_context($context); 156 157 // Make sure that all and only data for the course1 was exported. 158 // There is no way to fetch all data from writer as array so we need to fetch one-by-one for each data id. 159 $invaldfieldischecked = false; 160 foreach ($DB->get_records('customfield_data', []) as $dbrecord) { 161 $data = $writer->get_data(['Custom fields data', $dbrecord->id]); 162 if ($dbrecord->instanceid == $courses[1]->id) { 163 $this->assertEquals($dbrecord->fieldid, $data->fieldid); 164 $this->assertNotEmpty($data->fieldtype); 165 $this->assertNotEmpty($data->fieldshortname); 166 $this->assertNotEmpty($data->fieldname); 167 $invaldfieldischecked = $invaldfieldischecked ?: ($data->fieldid == $invalidfieldid); 168 } else { 169 $this->assertEmpty($data); 170 } 171 } 172 173 // Make sure field with was checked in this test. 174 $this->assertTrue($invaldfieldischecked); 175 } 176 177 /** 178 * Test for provider::delete_customfields_data() 179 */ 180 public function test_delete_customfields_data() { 181 global $USER, $DB; 182 $this->resetAfterTest(); 183 [ 184 'cffields' => $cffields, 185 'cfcats' => $cfcats, 186 'courses' => $courses, 187 ] = $this->generate_test_data(); 188 189 $approvedcontexts = new approved_contextlist($USER, 'core_course', [\context_course::instance($courses[1]->id)->id]); 190 provider::delete_customfields_data($approvedcontexts, 'core_course', 'course'); 191 $this->assertEmpty($DB->get_records('customfield_data', ['instanceid' => $courses[1]->id])); 192 $this->assertNotEmpty($DB->get_records('customfield_data', ['instanceid' => $courses[2]->id])); 193 } 194 195 /** 196 * Test for provider::delete_customfields_configuration() 197 */ 198 public function test_delete_customfields_configuration() { 199 global $USER, $DB; 200 $this->resetAfterTest(); 201 [ 202 'cffields' => $cffields, 203 'cfcats' => $cfcats, 204 'courses' => $courses, 205 ] = $this->generate_test_data(); 206 207 // Remember the list of fields in the category 2 before we delete it. 208 $catid1 = $cfcats[1]->get('id'); 209 $catid2 = $cfcats[2]->get('id'); 210 $fids2 = $DB->get_fieldset_select('customfield_field', 'id', 'categoryid=?', [$catid2]); 211 $this->assertNotEmpty($fids2); 212 list($fsql, $fparams) = $DB->get_in_or_equal($fids2, SQL_PARAMS_NAMED); 213 $this->assertNotEmpty($DB->get_records_select('customfield_data', 'fieldid ' . $fsql, $fparams)); 214 215 // A little hack here, modify customfields configuration so they have different itemids. 216 $DB->update_record('customfield_category', ['id' => $catid2, 'itemid' => 1]); 217 $contextlist = new approved_contextlist($USER, 'core_course', [\context_system::instance()->id]); 218 provider::delete_customfields_configuration($contextlist, 'core_course', 'course', '=:i', ['i' => 1]); 219 220 // Make sure everything for category $catid2 is gone but present for $catid1. 221 $this->assertEmpty($DB->get_records('customfield_category', ['id' => $catid2])); 222 $this->assertEmpty($DB->get_records_select('customfield_field', 'id ' . $fsql, $fparams)); 223 $this->assertEmpty($DB->get_records_select('customfield_data', 'fieldid ' . $fsql, $fparams)); 224 225 $this->assertNotEmpty($DB->get_records('customfield_category', ['id' => $catid1])); 226 $fids1 = $DB->get_fieldset_select('customfield_field', 'id', 'categoryid=?', [$catid1]); 227 list($fsql1, $fparams1) = $DB->get_in_or_equal($fids1, SQL_PARAMS_NAMED); 228 $this->assertNotEmpty($DB->get_records_select('customfield_field', 'id ' . $fsql1, $fparams1)); 229 $this->assertNotEmpty($DB->get_records_select('customfield_data', 'fieldid ' . $fsql1, $fparams1)); 230 } 231 232 /** 233 * Test for provider::delete_customfields_configuration_for_context() 234 */ 235 public function test_delete_customfields_configuration_for_context() { 236 global $USER, $DB; 237 $this->resetAfterTest(); 238 [ 239 'cffields' => $cffields, 240 'cfcats' => $cfcats, 241 'courses' => $courses, 242 ] = $this->generate_test_data(); 243 244 // Remember the list of fields in the category 2 before we delete it. 245 $catid1 = $cfcats[1]->get('id'); 246 $catid2 = $cfcats[2]->get('id'); 247 $fids2 = $DB->get_fieldset_select('customfield_field', 'id', 'categoryid=?', [$catid2]); 248 $this->assertNotEmpty($fids2); 249 list($fsql, $fparams) = $DB->get_in_or_equal($fids2, SQL_PARAMS_NAMED); 250 $this->assertNotEmpty($DB->get_records_select('customfield_data', 'fieldid ' . $fsql, $fparams)); 251 252 // A little hack here, modify customfields configuration so they have different contexts. 253 $context = \context_user::instance($USER->id); 254 $DB->update_record('customfield_category', ['id' => $catid2, 'contextid' => $context->id]); 255 provider::delete_customfields_configuration_for_context('core_course', 'course', $context); 256 257 // Make sure everything for category $catid2 is gone but present for $catid1. 258 $this->assertEmpty($DB->get_records('customfield_category', ['id' => $catid2])); 259 $this->assertEmpty($DB->get_records_select('customfield_field', 'id ' . $fsql, $fparams)); 260 $this->assertEmpty($DB->get_records_select('customfield_data', 'fieldid ' . $fsql, $fparams)); 261 262 $this->assertNotEmpty($DB->get_records('customfield_category', ['id' => $catid1])); 263 $fids1 = $DB->get_fieldset_select('customfield_field', 'id', 'categoryid=?', [$catid1]); 264 list($fsql1, $fparams1) = $DB->get_in_or_equal($fids1, SQL_PARAMS_NAMED); 265 $this->assertNotEmpty($DB->get_records_select('customfield_field', 'id ' . $fsql1, $fparams1)); 266 $this->assertNotEmpty($DB->get_records_select('customfield_data', 'fieldid ' . $fsql1, $fparams1)); 267 } 268 269 /** 270 * Test for provider::delete_customfields_data_for_context() 271 */ 272 public function test_delete_customfields_data_for_context() { 273 global $DB; 274 $this->resetAfterTest(); 275 [ 276 'cffields' => $cffields, 277 'cfcats' => $cfcats, 278 'courses' => $courses, 279 ] = $this->generate_test_data(); 280 281 provider::delete_customfields_data_for_context('core_course', 'course', 282 \context_course::instance($courses[1]->id)); 283 $fids2 = $DB->get_fieldset_select('customfield_field', 'id', '1=1', []); 284 list($fsql, $fparams) = $DB->get_in_or_equal($fids2, SQL_PARAMS_NAMED); 285 $fparams['course1'] = $courses[1]->id; 286 $fparams['course2'] = $courses[2]->id; 287 $this->assertEmpty($DB->get_records_select('customfield_data', 'instanceid = :course1 AND fieldid ' . $fsql, $fparams)); 288 $this->assertNotEmpty($DB->get_records_select('customfield_data', 'instanceid = :course2 AND fieldid ' . $fsql, $fparams)); 289 } 290 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body