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 * Data provider tests. 19 * 20 * @package mod_survey 21 * @category test 22 * @copyright 2018 Frédéric Massart 23 * @author Frédéric Massart <fred@branchup.tech> 24 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 25 */ 26 27defined('MOODLE_INTERNAL') || die(); 28global $CFG; 29 30use core_privacy\tests\provider_testcase; 31use core_privacy\local\request\approved_contextlist; 32use core_privacy\local\request\approved_userlist; 33use core_privacy\local\request\transform; 34use core_privacy\local\request\writer; 35use mod_survey\privacy\provider; 36 37require_once($CFG->dirroot . '/mod/survey/lib.php'); 38 39/** 40 * Data provider testcase class. 41 * 42 * @package mod_survey 43 * @category test 44 * @copyright 2018 Frédéric Massart 45 * @author Frédéric Massart <fred@branchup.tech> 46 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 47 */ 48class mod_survey_privacy_testcase extends provider_testcase { 49 50 public function setUp(): void { 51 global $PAGE; 52 $this->resetAfterTest(); 53 $PAGE->get_renderer('core'); 54 } 55 56 public function test_get_contexts_for_userid() { 57 $dg = $this->getDataGenerator(); 58 59 $c1 = $dg->create_course(); 60 $c2 = $dg->create_course(); 61 $cm1a = $dg->create_module('survey', ['template' => 1, 'course' => $c1]); 62 $cm1b = $dg->create_module('survey', ['template' => 2, 'course' => $c1]); 63 $cm1c = $dg->create_module('survey', ['template' => 2, 'course' => $c1]); 64 $cm2a = $dg->create_module('survey', ['template' => 1, 'course' => $c2]); 65 $cm2b = $dg->create_module('survey', ['template' => 1, 'course' => $c2]); 66 $u1 = $dg->create_user(); 67 $u2 = $dg->create_user(); 68 69 $this->create_answer($cm1a->id, 1, $u1->id); 70 $this->create_answer($cm1a->id, 1, $u2->id); 71 $this->create_answer($cm1b->id, 1, $u2->id); 72 $this->create_answer($cm2a->id, 1, $u1->id); 73 $this->create_analysis($cm2b->id, $u1->id); 74 $this->create_analysis($cm1c->id, $u2->id); 75 76 $contextids = provider::get_contexts_for_userid($u1->id)->get_contextids(); 77 $this->assertCount(3, $contextids); 78 $this->assertTrue(in_array(context_module::instance($cm1a->cmid)->id, $contextids)); 79 $this->assertTrue(in_array(context_module::instance($cm2a->cmid)->id, $contextids)); 80 $this->assertTrue(in_array(context_module::instance($cm2b->cmid)->id, $contextids)); 81 82 $contextids = provider::get_contexts_for_userid($u2->id)->get_contextids(); 83 $this->assertCount(3, $contextids); 84 $this->assertTrue(in_array(context_module::instance($cm1a->cmid)->id, $contextids)); 85 $this->assertTrue(in_array(context_module::instance($cm1b->cmid)->id, $contextids)); 86 $this->assertTrue(in_array(context_module::instance($cm1c->cmid)->id, $contextids)); 87 } 88 89 /** 90 * Test for provider::test_get_users_in_context(). 91 */ 92 public function test_get_users_in_context() { 93 $dg = $this->getDataGenerator(); 94 $component = 'mod_survey'; 95 96 $c1 = $dg->create_course(); 97 $c2 = $dg->create_course(); 98 $cm1a = $dg->create_module('survey', ['template' => 1, 'course' => $c1]); 99 $cm1b = $dg->create_module('survey', ['template' => 2, 'course' => $c1]); 100 $cm2 = $dg->create_module('survey', ['template' => 1, 'course' => $c2]); 101 $cm1acontext = context_module::instance($cm1a->cmid); 102 $cm1bcontext = context_module::instance($cm1b->cmid); 103 $cm2context = context_module::instance($cm2->cmid); 104 105 $u1 = $dg->create_user(); 106 $u2 = $dg->create_user(); 107 $bothusers = [$u1->id, $u2->id]; 108 sort($bothusers); 109 110 $this->create_answer($cm1a->id, 1, $u1->id); 111 $this->create_answer($cm1b->id, 1, $u1->id); 112 $this->create_answer($cm1b->id, 1, $u2->id); 113 $this->create_answer($cm2->id, 1, $u2->id); 114 $this->create_analysis($cm2->id, $u1->id); 115 116 // Cm1a should only contain u1. 117 $userlist = new \core_privacy\local\request\userlist($cm1acontext, $component); 118 provider::get_users_in_context($userlist); 119 120 $this->assertCount(1, $userlist); 121 $this->assertEquals([$u1->id], $userlist->get_userids()); 122 123 // Cm1b should contain u1 and u2 (both have answers). 124 $userlist = new \core_privacy\local\request\userlist($cm1bcontext, $component); 125 provider::get_users_in_context($userlist); 126 127 $this->assertCount(2, $userlist); 128 $actual = $userlist->get_userids(); 129 sort($actual); 130 $this->assertEquals($bothusers, $actual); 131 132 // Cm2 should contain u1 (analysis) and u2 (answer). 133 $userlist = new \core_privacy\local\request\userlist($cm2context, $component); 134 provider::get_users_in_context($userlist); 135 136 $this->assertCount(2, $userlist); 137 $actual = $userlist->get_userids(); 138 sort($actual); 139 $this->assertEquals($bothusers, $actual); 140 } 141 142 public function test_delete_data_for_all_users_in_context() { 143 global $DB; 144 $dg = $this->getDataGenerator(); 145 146 $c1 = $dg->create_course(); 147 $cm1a = $dg->create_module('survey', ['template' => 1, 'course' => $c1]); 148 $cm1b = $dg->create_module('survey', ['template' => 2, 'course' => $c1]); 149 $cm1c = $dg->create_module('survey', ['template' => 2, 'course' => $c1]); 150 $u1 = $dg->create_user(); 151 $u2 = $dg->create_user(); 152 153 $this->create_answer($cm1a->id, 1, $u1->id); 154 $this->create_answer($cm1a->id, 1, $u2->id); 155 $this->create_answer($cm1b->id, 1, $u2->id); 156 $this->create_answer($cm1c->id, 1, $u1->id); 157 $this->create_analysis($cm1a->id, $u1->id); 158 $this->create_analysis($cm1b->id, $u1->id); 159 $this->create_analysis($cm1a->id, $u2->id); 160 $this->create_analysis($cm1c->id, $u2->id); 161 162 $this->assertTrue($DB->record_exists('survey_answers', ['userid' => $u1->id, 'survey' => $cm1a->id])); 163 $this->assertTrue($DB->record_exists('survey_answers', ['userid' => $u1->id, 'survey' => $cm1c->id])); 164 $this->assertTrue($DB->record_exists('survey_answers', ['userid' => $u2->id, 'survey' => $cm1a->id])); 165 $this->assertTrue($DB->record_exists('survey_answers', ['userid' => $u2->id, 'survey' => $cm1b->id])); 166 $this->assertTrue($DB->record_exists('survey_analysis', ['userid' => $u1->id, 'survey' => $cm1a->id])); 167 $this->assertTrue($DB->record_exists('survey_analysis', ['userid' => $u1->id, 'survey' => $cm1b->id])); 168 $this->assertTrue($DB->record_exists('survey_analysis', ['userid' => $u2->id, 'survey' => $cm1a->id])); 169 $this->assertTrue($DB->record_exists('survey_analysis', ['userid' => $u2->id, 'survey' => $cm1c->id])); 170 171 // Deleting the course does nothing. 172 provider::delete_data_for_all_users_in_context(context_course::instance($c1->id)); 173 $this->assertTrue($DB->record_exists('survey_answers', ['userid' => $u1->id, 'survey' => $cm1a->id])); 174 $this->assertTrue($DB->record_exists('survey_answers', ['userid' => $u1->id, 'survey' => $cm1c->id])); 175 $this->assertTrue($DB->record_exists('survey_answers', ['userid' => $u2->id, 'survey' => $cm1a->id])); 176 $this->assertTrue($DB->record_exists('survey_answers', ['userid' => $u2->id, 'survey' => $cm1b->id])); 177 $this->assertTrue($DB->record_exists('survey_analysis', ['userid' => $u1->id, 'survey' => $cm1a->id])); 178 $this->assertTrue($DB->record_exists('survey_analysis', ['userid' => $u1->id, 'survey' => $cm1b->id])); 179 $this->assertTrue($DB->record_exists('survey_analysis', ['userid' => $u2->id, 'survey' => $cm1a->id])); 180 $this->assertTrue($DB->record_exists('survey_analysis', ['userid' => $u2->id, 'survey' => $cm1c->id])); 181 182 provider::delete_data_for_all_users_in_context(context_module::instance($cm1c->cmid)); 183 $this->assertTrue($DB->record_exists('survey_answers', ['userid' => $u1->id, 'survey' => $cm1a->id])); 184 $this->assertFalse($DB->record_exists('survey_answers', ['userid' => $u1->id, 'survey' => $cm1c->id])); 185 $this->assertTrue($DB->record_exists('survey_answers', ['userid' => $u2->id, 'survey' => $cm1a->id])); 186 $this->assertTrue($DB->record_exists('survey_answers', ['userid' => $u2->id, 'survey' => $cm1b->id])); 187 $this->assertTrue($DB->record_exists('survey_analysis', ['userid' => $u1->id, 'survey' => $cm1a->id])); 188 $this->assertTrue($DB->record_exists('survey_analysis', ['userid' => $u1->id, 'survey' => $cm1b->id])); 189 $this->assertTrue($DB->record_exists('survey_analysis', ['userid' => $u2->id, 'survey' => $cm1a->id])); 190 $this->assertFalse($DB->record_exists('survey_analysis', ['userid' => $u2->id, 'survey' => $cm1c->id])); 191 192 provider::delete_data_for_all_users_in_context(context_module::instance($cm1a->cmid)); 193 $this->assertFalse($DB->record_exists('survey_answers', ['userid' => $u1->id, 'survey' => $cm1a->id])); 194 $this->assertFalse($DB->record_exists('survey_answers', ['userid' => $u1->id, 'survey' => $cm1c->id])); 195 $this->assertFalse($DB->record_exists('survey_answers', ['userid' => $u2->id, 'survey' => $cm1a->id])); 196 $this->assertTrue($DB->record_exists('survey_answers', ['userid' => $u2->id, 'survey' => $cm1b->id])); 197 $this->assertFalse($DB->record_exists('survey_analysis', ['userid' => $u1->id, 'survey' => $cm1a->id])); 198 $this->assertTrue($DB->record_exists('survey_analysis', ['userid' => $u1->id, 'survey' => $cm1b->id])); 199 $this->assertFalse($DB->record_exists('survey_analysis', ['userid' => $u2->id, 'survey' => $cm1a->id])); 200 $this->assertFalse($DB->record_exists('survey_analysis', ['userid' => $u2->id, 'survey' => $cm1c->id])); 201 } 202 203 public function test_delete_data_for_user() { 204 global $DB; 205 $dg = $this->getDataGenerator(); 206 207 $c1 = $dg->create_course(); 208 $cm1a = $dg->create_module('survey', ['template' => 1, 'course' => $c1]); 209 $cm1b = $dg->create_module('survey', ['template' => 2, 'course' => $c1]); 210 $cm1c = $dg->create_module('survey', ['template' => 2, 'course' => $c1]); 211 $u1 = $dg->create_user(); 212 $u2 = $dg->create_user(); 213 214 $this->create_answer($cm1a->id, 1, $u1->id); 215 $this->create_answer($cm1a->id, 1, $u2->id); 216 $this->create_answer($cm1b->id, 1, $u2->id); 217 $this->create_answer($cm1c->id, 1, $u1->id); 218 $this->create_analysis($cm1a->id, $u1->id); 219 $this->create_analysis($cm1b->id, $u1->id); 220 $this->create_analysis($cm1a->id, $u2->id); 221 $this->create_analysis($cm1c->id, $u2->id); 222 223 $this->assertTrue($DB->record_exists('survey_answers', ['userid' => $u1->id, 'survey' => $cm1a->id])); 224 $this->assertTrue($DB->record_exists('survey_answers', ['userid' => $u1->id, 'survey' => $cm1c->id])); 225 $this->assertTrue($DB->record_exists('survey_answers', ['userid' => $u2->id, 'survey' => $cm1a->id])); 226 $this->assertTrue($DB->record_exists('survey_answers', ['userid' => $u2->id, 'survey' => $cm1b->id])); 227 $this->assertTrue($DB->record_exists('survey_analysis', ['userid' => $u1->id, 'survey' => $cm1a->id])); 228 $this->assertTrue($DB->record_exists('survey_analysis', ['userid' => $u1->id, 'survey' => $cm1b->id])); 229 $this->assertTrue($DB->record_exists('survey_analysis', ['userid' => $u2->id, 'survey' => $cm1a->id])); 230 $this->assertTrue($DB->record_exists('survey_analysis', ['userid' => $u2->id, 'survey' => $cm1c->id])); 231 232 provider::delete_data_for_user(new approved_contextlist($u1, 'mod_survey', [ 233 context_course::instance($c1->id)->id, 234 context_module::instance($cm1a->cmid)->id, 235 context_module::instance($cm1b->cmid)->id, 236 ])); 237 $this->assertFalse($DB->record_exists('survey_answers', ['userid' => $u1->id, 'survey' => $cm1a->id])); 238 $this->assertTrue($DB->record_exists('survey_answers', ['userid' => $u1->id, 'survey' => $cm1c->id])); 239 $this->assertTrue($DB->record_exists('survey_answers', ['userid' => $u2->id, 'survey' => $cm1a->id])); 240 $this->assertTrue($DB->record_exists('survey_answers', ['userid' => $u2->id, 'survey' => $cm1b->id])); 241 $this->assertFalse($DB->record_exists('survey_analysis', ['userid' => $u1->id, 'survey' => $cm1a->id])); 242 $this->assertFalse($DB->record_exists('survey_analysis', ['userid' => $u1->id, 'survey' => $cm1b->id])); 243 $this->assertTrue($DB->record_exists('survey_analysis', ['userid' => $u2->id, 'survey' => $cm1a->id])); 244 $this->assertTrue($DB->record_exists('survey_analysis', ['userid' => $u2->id, 'survey' => $cm1c->id])); 245 } 246 247 /** 248 * Test for provider::delete_data_for_users(). 249 */ 250 public function test_delete_data_for_users() { 251 global $DB; 252 $dg = $this->getDataGenerator(); 253 $component = 'mod_survey'; 254 255 $c1 = $dg->create_course(); 256 $cm1a = $dg->create_module('survey', ['template' => 1, 'course' => $c1]); 257 $cm1b = $dg->create_module('survey', ['template' => 2, 'course' => $c1]); 258 $cm1c = $dg->create_module('survey', ['template' => 2, 'course' => $c1]); 259 $cm1acontext = context_module::instance($cm1a->cmid); 260 $cm1bcontext = context_module::instance($cm1b->cmid); 261 262 $u1 = $dg->create_user(); 263 $u2 = $dg->create_user(); 264 265 $this->create_answer($cm1a->id, 1, $u1->id); 266 $this->create_answer($cm1a->id, 1, $u2->id); 267 $this->create_analysis($cm1a->id, $u1->id); 268 $this->create_analysis($cm1a->id, $u2->id); 269 $this->create_answer($cm1b->id, 1, $u2->id); 270 $this->create_analysis($cm1b->id, $u1->id); 271 $this->create_answer($cm1c->id, 1, $u1->id); 272 $this->create_analysis($cm1c->id, $u2->id); 273 274 // Confirm data exists before deletion. 275 $this->assertTrue($DB->record_exists('survey_answers', ['userid' => $u1->id, 'survey' => $cm1a->id])); 276 $this->assertTrue($DB->record_exists('survey_answers', ['userid' => $u1->id, 'survey' => $cm1c->id])); 277 $this->assertTrue($DB->record_exists('survey_answers', ['userid' => $u2->id, 'survey' => $cm1a->id])); 278 $this->assertTrue($DB->record_exists('survey_answers', ['userid' => $u2->id, 'survey' => $cm1b->id])); 279 $this->assertTrue($DB->record_exists('survey_analysis', ['userid' => $u1->id, 'survey' => $cm1a->id])); 280 $this->assertTrue($DB->record_exists('survey_analysis', ['userid' => $u1->id, 'survey' => $cm1b->id])); 281 $this->assertTrue($DB->record_exists('survey_analysis', ['userid' => $u2->id, 'survey' => $cm1a->id])); 282 $this->assertTrue($DB->record_exists('survey_analysis', ['userid' => $u2->id, 'survey' => $cm1c->id])); 283 284 // Ensure only approved user data is deleted. 285 $approveduserids = [$u1->id]; 286 $approvedlist = new approved_userlist($cm1acontext, $component, $approveduserids); 287 provider::delete_data_for_users($approvedlist); 288 289 $this->assertFalse($DB->record_exists('survey_answers', ['userid' => $u1->id, 'survey' => $cm1a->id])); 290 $this->assertFalse($DB->record_exists('survey_analysis', ['userid' => $u1->id, 'survey' => $cm1a->id])); 291 $this->assertTrue($DB->record_exists('survey_answers', ['userid' => $u2->id, 'survey' => $cm1a->id])); 292 $this->assertTrue($DB->record_exists('survey_analysis', ['userid' => $u2->id, 'survey' => $cm1a->id])); 293 294 $approveduserids = [$u1->id, $u2->id]; 295 $approvedlist = new approved_userlist($cm1bcontext, $component, $approveduserids); 296 provider::delete_data_for_users($approvedlist); 297 298 $this->assertFalse($DB->record_exists('survey_answers', ['survey' => $cm1b->id])); 299 $this->assertFalse($DB->record_exists('survey_analysis', ['survey' => $cm1b->id])); 300 301 $this->assertTrue($DB->record_exists('survey_answers', ['userid' => $u1->id, 'survey' => $cm1c->id])); 302 $this->assertTrue($DB->record_exists('survey_analysis', ['userid' => $u2->id, 'survey' => $cm1c->id])); 303 } 304 305 public function test_export_data_for_user() { 306 global $DB; 307 $dg = $this->getDataGenerator(); 308 309 $templates = $DB->get_records_menu('survey', array('template' => 0), 'name', 'name, id'); 310 311 $c1 = $dg->create_course(); 312 $s1a = $dg->create_module('survey', ['template' => $templates['attlsname'], 'course' => $c1]); 313 $s1b = $dg->create_module('survey', ['template' => $templates['ciqname'], 'course' => $c1]); 314 $s1c = $dg->create_module('survey', ['template' => $templates['collesapname'], 'course' => $c1]); 315 $u1 = $dg->create_user(); 316 $u2 = $dg->create_user(); 317 318 $s1actx = context_module::instance($s1a->cmid); 319 $s1bctx = context_module::instance($s1b->cmid); 320 $s1cctx = context_module::instance($s1c->cmid); 321 322 $this->answer_survey($s1a, $u1, $c1, $s1actx); 323 $this->answer_survey($s1b, $u1, $c1, $s1bctx); 324 $this->create_analysis($s1a->id, $u1->id, 'Hello,'); 325 326 $this->answer_survey($s1a, $u2, $c1, $s1actx); 327 $this->answer_survey($s1c, $u2, $c1, $s1cctx); 328 $this->create_analysis($s1b->id, $u2->id, 'World!'); 329 330 provider::export_user_data(new approved_contextlist($u1, 'mod_survey', [$s1actx->id, $s1bctx->id, $s1cctx->id])); 331 332 $data = writer::with_context($s1actx)->get_data([]); 333 $this->assertNotEmpty($data); 334 $this->assert_exported_answers($data->answers, $u1, $s1a); 335 $data = writer::with_context($s1actx)->get_related_data([], 'survey_analysis'); 336 $this->assertEquals('Hello,', $data->notes); 337 338 $data = writer::with_context($s1bctx)->get_data([]); 339 $this->assertNotEmpty($data); 340 $this->assert_exported_answers($data->answers, $u1, $s1b); 341 $data = writer::with_context($s1bctx)->get_related_data([], 'survey_analysis'); 342 $this->assertEmpty($data); 343 344 $data = writer::with_context($s1cctx)->get_data([]); 345 $this->assertEmpty($data); 346 $data = writer::with_context($s1cctx)->get_related_data([], 'survey_analysis'); 347 $this->assertEmpty($data); 348 349 writer::reset(); 350 provider::export_user_data(new approved_contextlist($u2, 'mod_survey', [$s1actx->id, $s1bctx->id, $s1cctx->id])); 351 352 $data = writer::with_context($s1actx)->get_data([]); 353 $this->assertNotEmpty($data); 354 $this->assert_exported_answers($data->answers, $u2, $s1a); 355 $data = writer::with_context($s1actx)->get_related_data([], 'survey_analysis'); 356 $this->assertEmpty($data); 357 358 $data = writer::with_context($s1bctx)->get_data([]); 359 $this->assertEmpty($data); 360 $data = writer::with_context($s1bctx)->get_related_data([], 'survey_analysis'); 361 $this->assertEquals('World!', $data->notes); 362 363 $data = writer::with_context($s1cctx)->get_data([]); 364 $this->assertNotEmpty($data); 365 $this->assert_exported_answers($data->answers, $u2, $s1c); 366 $data = writer::with_context($s1cctx)->get_related_data([], 'survey_analysis'); 367 $this->assertEmpty($data); 368 } 369 370 /** 371 * Answer a survey in a predictable manner. 372 * 373 * @param stdClass $survey The survey. 374 * @param stdClass $user The user. 375 * @param stdClass $course The course. 376 * @param context_module $context The module context. 377 * @return void 378 */ 379 protected function answer_survey($survey, $user, $course, context_module $context) { 380 global $USER; 381 382 $userid = $user->id; 383 $questions = survey_get_questions($survey); 384 $answer = function(&$answers, $q) use ($userid) { 385 $key = 'q' . ($q->type == 2 ? 'P' : '') . $q->id; 386 387 if ($q->type < 1) { 388 $a = "A:{$q->id}:{$userid}"; 389 $answers[$key] = $a; 390 391 } else if ($q->type < 3) { 392 $options = explode(',', get_string($q->options, 'mod_survey')); 393 $answers[$key] = ($q->id + $userid) % count($options) + 1; 394 395 } else { 396 $options = explode(',', get_string($q->options, 'mod_survey')); 397 $answers["q{$q->id}"] = ($q->id + $userid) % count($options) + 1; 398 $answers["qP{$q->id}"] = ($q->id + $userid + 1) % count($options) + 1; 399 } 400 401 }; 402 403 foreach ($questions as $q) { 404 if ($q->type < 0) { 405 continue; 406 } else if ($q->type > 0 && $q->multi) { 407 $subquestions = survey_get_subquestions($q); 408 foreach ($subquestions as $sq) { 409 $answer($answers, $sq); 410 } 411 } else { 412 $answer($answers, $q); 413 } 414 } 415 416 $origuser = $USER; 417 $this->setUser($user); 418 survey_save_answers($survey, $answers, $course, $context); 419 $this->setUser($origuser); 420 } 421 422 /** 423 * Assert the answers provided to a survey. 424 * 425 * @param array $answers The answers. 426 * @param object $user The user. 427 * @param object $survey The survey. 428 * @return void 429 */ 430 protected function assert_exported_answers($answers, $user, $survey) { 431 global $DB; 432 433 $userid = $user->id; 434 $questionids = explode(',', $survey->questions); 435 $topquestions = $DB->get_records_list('survey_questions', 'id', $questionids, 'id'); 436 $questions = []; 437 438 foreach ($topquestions as $q) { 439 if ($q->type < 0) { 440 continue; 441 } else if ($q->type > 0 && $q->multi) { 442 $questionids = explode(',', $q->multi); 443 $subqs = $DB->get_records_list('survey_questions', 'id', $questionids, 'id'); 444 } else { 445 $subqs = [$q]; 446 } 447 foreach ($subqs as $sq) { 448 $questions[] = $sq; 449 } 450 } 451 452 $this->assertCount(count($questions), $answers); 453 454 $answer = reset($answers); 455 foreach ($questions as $question) { 456 $qtype = $question->type; 457 $question = survey_translate_question($question); 458 $options = $qtype > 0 ? explode(',', $question->options) : '-'; 459 $this->assertEquals($question->text, $answer['question']['text']); 460 $this->assertEquals($question->shorttext, $answer['question']['shorttext']); 461 $this->assertEquals($question->intro, $answer['question']['intro']); 462 $this->assertEquals($options, $answer['question']['options']); 463 464 if ($qtype < 1) { 465 $this->assertEquals("A:{$question->id}:{$userid}", $answer['answer']['actual']); 466 467 } else if ($qtype == 1 || $qtype == 2) { 468 $chosen = ($question->id + $userid) % count($options); 469 $key = $qtype == 1 ? 'actual' : 'preferred'; 470 $this->assertEquals($options[$chosen], $answer['answer'][$key]); 471 472 } else { 473 $chosen = ($question->id + $userid) % count($options); 474 $this->assertEquals($options[$chosen], $answer['answer']['actual']); 475 $chosen = ($question->id + $userid + 1) % count($options); 476 $this->assertEquals($options[$chosen], $answer['answer']['preferred']); 477 } 478 479 // Grab next answer, if any. 480 $answer = next($answers); 481 } 482 483 } 484 485 /** 486 * Create analysis. 487 * 488 * @param int $surveyid The survey ID. 489 * @param int $userid The user ID. 490 * @param string $notes The nodes. 491 * @return stdClass 492 */ 493 protected function create_analysis($surveyid, $userid, $notes = '') { 494 global $DB; 495 $record = (object) [ 496 'survey' => $surveyid, 497 'userid' => $userid, 498 'notes' => $notes 499 ]; 500 $record->id = $DB->insert_record('survey_analysis', $record); 501 return $record; 502 } 503 504 /** 505 * Create answer. 506 * 507 * @param int $surveyid The survey ID. 508 * @param int $questionid The question ID. 509 * @param int $userid The user ID. 510 * @param string $answer1 The first answer field. 511 * @param string $answer2 The second answer field. 512 * @return stdClass 513 */ 514 protected function create_answer($surveyid, $questionid, $userid, $answer1 = '', $answer2 = '') { 515 global $DB; 516 $record = (object) [ 517 'survey' => $surveyid, 518 'question' => $questionid, 519 'userid' => $userid, 520 'answer1' => $answer1, 521 'answer2' => $answer2, 522 'time' => time() 523 ]; 524 $record->id = $DB->insert_record('survey_answers', $record); 525 return $record; 526 } 527 528} 529