Differences Between: [Versions 311 and 402]
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 * Unit tests for data_get_all_recordsids(), data_get_advance_search_ids(), data_get_record_ids(), 19 * and data_get_advanced_search_sql() 20 * 21 * @package mod_data 22 * @category phpunit 23 * @copyright 2012 Adrian Greeve 24 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 25 */ 26 27 namespace mod_data\search; 28 29 defined('MOODLE_INTERNAL') || die(); 30 31 global $CFG; 32 require_once($CFG->dirroot . '/mod/data/lib.php'); 33 require_once($CFG->dirroot . '/lib/datalib.php'); 34 require_once($CFG->dirroot . '/lib/csvlib.class.php'); 35 require_once($CFG->dirroot . '/search/tests/fixtures/testable_core_search.php'); 36 require_once($CFG->dirroot . '/mod/data/tests/generator/lib.php'); 37 38 /** 39 * Unit tests for {@see data_get_all_recordids()}. 40 * {@see data_get_advanced_search_ids()} 41 * {@see data_get_record_ids()} 42 * {@see data_get_advanced_search_sql()} 43 * 44 * @package mod_data 45 * @copyright 2012 Adrian Greeve 46 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 47 */ 48 class search_test extends \advanced_testcase { 49 /** 50 * @var stdObject $recorddata An object that holds information from the table data. 51 */ 52 public $recorddata = null; 53 /** 54 * @var int $recordcontentid The content ID. 55 */ 56 public $recordcontentid = null; 57 /** 58 * @var int $recordrecordid The record ID. 59 */ 60 public $recordrecordid = null; 61 /** 62 * @var int $recordfieldid The field ID. 63 */ 64 public $recordfieldid = null; 65 /** 66 * @var array $recordsearcharray An array of stdClass which contains search criteria. 67 */ 68 public $recordsearcharray = null; 69 70 // CONSTANTS 71 72 /** 73 * @var int $datarecordcount The number of records in the database. 74 */ 75 public $datarecordcount = 100; 76 77 /** 78 * @var int $groupdatarecordcount The number of records in the database in groups 0 and 1. 79 */ 80 public $groupdatarecordcount = 75; 81 82 /** 83 * @var array $datarecordset Expected record IDs. 84 */ 85 public $datarecordset = array('0' => '6'); 86 87 /** 88 * @var array $finalrecord Final record for comparison with test four. 89 */ 90 public $finalrecord = array(); 91 92 /** 93 * @var int $approvedatarecordcount The number of approved records in the database. 94 */ 95 public $approvedatarecordcount = 89; 96 97 /** 98 * @var string Area id 99 */ 100 protected $databaseentryareaid = null; 101 102 /** 103 * Set up function. In this instance we are setting up database 104 * records to be used in the unit tests. 105 */ 106 protected function setUp(): void { 107 global $DB, $CFG; 108 parent::setUp(); 109 110 $this->resetAfterTest(true); 111 112 set_config('enableglobalsearch', true); 113 114 $this->databaseentryareaid = \core_search\manager::generate_areaid('mod_data', 'entry'); 115 116 // Set \core_search::instance to the mock_search_engine as we don't require the search engine to be working to test this. 117 $search = \testable_core_search::instance(); 118 119 } 120 121 /** 122 * Test 1: The function data_get_all_recordids. 123 * 124 * Test 2: This tests the data_get_advance_search_ids() function. The function takes a set 125 * of all the record IDs in the database and then with the search details ($this->recordsearcharray) 126 * returns a comma seperated string of record IDs that match the search criteria. 127 * 128 * Test 3: This function tests data_get_recordids(). This is the function that is nested in the last 129 * function (see data_get_advance_search_ids). This function takes a couple of 130 * extra parameters. $alias is the field alias used in the sql query and $commaid 131 * is a comma seperated string of record IDs. 132 * 133 * Test 3.1: This tests that if no recordids are provided (In a situation where a search is done on an empty database) 134 * That an empty array is returned. 135 * 136 * Test 4: data_get_advanced_search_sql provides an array which contains an sql string to be used for displaying records 137 * to the user when they use the advanced search criteria and the parameters that go with the sql statement. This test 138 * takes that information and does a search on the database, returning a record. 139 * 140 * Test 5: Returning to data_get_all_recordids(). Here we are ensuring that the total amount of record ids is reduced to 141 * match the group conditions that are provided. There are 25 entries which relate to group 2. They are removed 142 * from the total so we should only have 75 records total. 143 * 144 * Test 6: data_get_all_recordids() again. This time we are testing approved database records. We only want to 145 * display the records that have been approved. In this record set we have 89 approved records. 146 */ 147 public function test_advanced_search_sql_section() { 148 global $DB; 149 150 // we already have 2 users, we need 98 more - let's ignore the fact that guest can not post anywhere 151 // We reset the user sequence here to ensure we get the expected numbers. 152 // TODO: Invent a better way for managing data file input against database sequence id's. 153 $DB->get_manager()->reset_sequence('user'); 154 for($i=3;$i<=100;$i++) { 155 $this->getDataGenerator()->create_user(); 156 } 157 158 // create database module - there should be more of these I guess 159 $course = $this->getDataGenerator()->create_course(); 160 $data = $this->getDataGenerator()->create_module('data', array('course'=>$course->id)); 161 $this->recorddata = $data; 162 163 // Set up data for the test database. 164 $files = array( 165 'data_fields' => __DIR__.'/../fixtures/test_data_fields.csv', 166 'data_records' => __DIR__.'/../fixtures/test_data_records.csv', 167 'data_content' => __DIR__.'/../fixtures/test_data_content.csv', 168 ); 169 $this->dataset_from_files($files)->to_database(); 170 // Set dataid to the correct value now the data has been inserted by csv file. 171 $DB->execute('UPDATE {data_fields} SET dataid = ?', array($data->id)); 172 $DB->execute('UPDATE {data_records} SET dataid = ?', array($data->id)); 173 174 // Create the search array which contains our advanced search criteria. 175 $fieldinfo = array('0' => new \stdClass(), 176 '1' => new \stdClass(), 177 '2' => new \stdClass(), 178 '3' => new \stdClass(), 179 '4' => new \stdClass()); 180 $fieldinfo['0']->id = 1; 181 $fieldinfo['0']->data = '3.721,46.6126'; 182 $fieldinfo['1']->id = 2; 183 $fieldinfo['1']->data = 'Hahn Premium'; 184 $fieldinfo['2']->id = 5; 185 $fieldinfo['2']->data = 'Female'; 186 $fieldinfo['3']->id = 7; 187 $fieldinfo['3']->data = 'kel'; 188 $fieldinfo['4']->id = 9; 189 $fieldinfo['4']->data = 'VIC'; 190 191 foreach($fieldinfo as $field) { 192 $searchfield = data_get_field_from_id($field->id, $data); 193 if ($field->id == 2) { 194 $searchfield->field->param1 = 'Hahn Premium'; 195 $val = array(); 196 $val['selected'] = array('0' => 'Hahn Premium'); 197 $val['allrequired'] = 0; 198 } else { 199 $val = $field->data; 200 } 201 $search_array[$field->id] = new \stdClass(); 202 list($search_array[$field->id]->sql, $search_array[$field->id]->params) = $searchfield->generate_sql('c' . $field->id, $val); 203 } 204 205 $this->recordsearcharray = $search_array; 206 207 // Setting up the comparison stdClass for the last test. 208 $user = $DB->get_record('user', array('id'=>6)); 209 $this->finalrecord[6] = new \stdClass(); 210 $this->finalrecord[6]->id = 6; 211 $this->finalrecord[6]->approved = 1; 212 $this->finalrecord[6]->timecreated = 1234567891; 213 $this->finalrecord[6]->timemodified = 1234567892; 214 $this->finalrecord[6]->userid = 6; 215 $this->finalrecord[6]->firstname = $user->firstname; 216 $this->finalrecord[6]->lastname = $user->lastname; 217 $this->finalrecord[6]->firstnamephonetic = $user->firstnamephonetic; 218 $this->finalrecord[6]->lastnamephonetic = $user->lastnamephonetic; 219 $this->finalrecord[6]->middlename = $user->middlename; 220 $this->finalrecord[6]->alternatename = $user->alternatename; 221 $this->finalrecord[6]->picture = $user->picture; 222 $this->finalrecord[6]->imagealt = $user->imagealt; 223 $this->finalrecord[6]->email = $user->email; 224 225 // Test 1 226 $recordids = data_get_all_recordids($this->recorddata->id); 227 $this->assertEquals(count($recordids), $this->datarecordcount); 228 229 // Test 2 230 $key = array_keys($this->recordsearcharray); 231 $alias = $key[0]; 232 $newrecordids = data_get_recordids($alias, $this->recordsearcharray, $this->recorddata->id, $recordids); 233 $this->assertEquals($this->datarecordset, $newrecordids); 234 235 // Test 3 236 $newrecordids = data_get_advance_search_ids($recordids, $this->recordsearcharray, $this->recorddata->id); 237 $this->assertEquals($this->datarecordset, $newrecordids); 238 239 // Test 3.1 240 $resultrecordids = data_get_advance_search_ids(array(), $this->recordsearcharray, $this->recorddata->id); 241 $this->assertEmpty($resultrecordids); 242 243 // Test 4 244 $sortorder = 'ORDER BY r.timecreated ASC , r.id ASC'; 245 $html = data_get_advanced_search_sql('0', $this->recorddata, $newrecordids, '', $sortorder); 246 $allparams = array_merge($html['params'], array('dataid' => $this->recorddata->id)); 247 $records = $DB->get_records_sql($html['sql'], $allparams); 248 $this->assertEquals($records, $this->finalrecord); 249 250 // Test 5 251 $groupsql = " AND (r.groupid = :currentgroup OR r.groupid = 0)"; 252 $params = array('currentgroup' => 1); 253 $recordids = data_get_all_recordids($this->recorddata->id, $groupsql, $params); 254 $this->assertEquals($this->groupdatarecordcount, count($recordids)); 255 256 // Test 6 257 $approvesql = ' AND r.approved=1 '; 258 $recordids = data_get_all_recordids($this->recorddata->id, $approvesql, $params); 259 $this->assertEquals($this->approvedatarecordcount, count($recordids)); 260 } 261 262 public function test_advanced_search_tags() { 263 $this->resetAfterTest(); 264 $this->setAdminUser(); 265 266 // Setup test data. 267 $datagenerator = $this->getDataGenerator()->get_plugin_generator('mod_data'); 268 $course1 = $this->getDataGenerator()->create_course(); 269 270 $fieldrecord = new \stdClass(); 271 $fieldrecord->name = 'field-1'; 272 $fieldrecord->type = 'text'; 273 $fieldrecord->titlefield = true; 274 275 $data1 = $this->getDataGenerator()->create_module('data', array('course' => $course1->id, 'approval' => true)); 276 $field1 = $datagenerator->create_field($fieldrecord, $data1); 277 278 $record11 = $datagenerator->create_entry($data1, [$field1->field->id => 'value11'], 0, ['Cats', 'Dogs']); 279 $record12 = $datagenerator->create_entry($data1, [$field1->field->id => 'value12'], 0, ['Cats', 'mice']); 280 $record13 = $datagenerator->create_entry($data1, [$field1->field->id => 'value13'], 0, ['Bats']); 281 282 $searcharray = []; 283 $searcharray[DATA_TAGS] = new \stdClass(); 284 $searcharray[DATA_TAGS]->params = []; 285 $searcharray[DATA_TAGS]->rawtagnames = ['Cats']; 286 $searcharray[DATA_TAGS]->sql = ''; 287 288 $recordids = data_get_all_recordids($data1->id); 289 $newrecordids = data_get_advance_search_ids($recordids, $searcharray, $data1->id); 290 291 $this->assertContainsEquals($record11, $newrecordids); 292 $this->assertContainsEquals($record12, $newrecordids); 293 $this->assertNotContainsEquals($record13, $newrecordids); 294 } 295 296 /** 297 * Indexing database entries contents. 298 * 299 * @return void 300 */ 301 public function test_data_entries_indexing() { 302 global $DB; 303 304 // Returns the instance as long as the area is supported. 305 $searcharea = \core_search\manager::get_search_area($this->databaseentryareaid); 306 $this->assertInstanceOf('\mod_data\search\entry', $searcharea); 307 308 $user1 = self::getDataGenerator()->create_user(); 309 310 $course1 = self::getDataGenerator()->create_course(); 311 312 $this->getDataGenerator()->enrol_user($user1->id, $course1->id, 'student'); 313 314 $record = new \stdClass(); 315 $record->course = $course1->id; 316 317 $this->setUser($user1); 318 319 // Available for both student and teacher. 320 $data1 = $this->getDataGenerator()->create_module('data', $record); 321 322 // Excluding LatLong and Picture as we aren't indexing LatLong and Picture fields any way 323 // ...and they're complex and not of any use to consider for this test. 324 // Excluding File as we are indexing files seperately and its complex to implement. 325 $fieldtypes = array( 'checkbox', 'date', 'menu', 'multimenu', 'number', 'radiobutton', 'text', 'textarea', 'url' ); 326 327 $this->create_default_data_fields($fieldtypes, $data1); 328 329 $data1record1id = $this->create_default_data_record($data1); 330 // All records. 331 $recordset = $searcharea->get_recordset_by_timestamp(0); 332 333 $this->assertTrue($recordset->valid()); 334 335 $nrecords = 0; 336 foreach ($recordset as $record) { 337 $this->assertInstanceOf('stdClass', $record); 338 $doc = $searcharea->get_document($record); 339 $this->assertInstanceOf('\core_search\document', $doc); 340 $nrecords++; 341 } 342 343 // If there would be an error/failure in the foreach above the recordset would be closed on shutdown. 344 $recordset->close(); 345 $this->assertEquals(1, $nrecords); 346 347 // The +2 is to prevent race conditions. 348 $recordset = $searcharea->get_recordset_by_timestamp(time() + 2); 349 350 // No new records. 351 $this->assertFalse($recordset->valid()); 352 $recordset->close(); 353 354 // Create a second database, also with one record. 355 $data2 = $this->getDataGenerator()->create_module('data', ['course' => $course1->id]); 356 $this->create_default_data_fields($fieldtypes, $data2); 357 $this->create_default_data_record($data2); 358 359 // Test indexing with contexts. 360 $rs = $searcharea->get_document_recordset(0, \context_module::instance($data1->cmid)); 361 $this->assertEquals(1, iterator_count($rs)); 362 $rs->close(); 363 $rs = $searcharea->get_document_recordset(0, \context_module::instance($data2->cmid)); 364 $this->assertEquals(1, iterator_count($rs)); 365 $rs->close(); 366 $rs = $searcharea->get_document_recordset(0, \context_course::instance($course1->id)); 367 $this->assertEquals(2, iterator_count($rs)); 368 $rs->close(); 369 } 370 371 /** 372 * Document contents. 373 * 374 * @return void 375 */ 376 public function test_data_entries_document() { 377 global $DB; 378 379 // Returns the instance as long as the area is supported. 380 $searcharea = \core_search\manager::get_search_area($this->databaseentryareaid); 381 $this->assertInstanceOf('\mod_data\search\entry', $searcharea); 382 383 $user1 = self::getDataGenerator()->create_user(); 384 385 $course = self::getDataGenerator()->create_course(); 386 387 $this->getDataGenerator()->enrol_user($user1->id, $course->id, 'student'); 388 389 $record = new \stdClass(); 390 $record->course = $course->id; 391 392 $this->setAdminUser(); 393 394 // First Case. 395 $data1 = $this->getDataGenerator()->create_module('data', $record); 396 397 $fieldtypes = array( 'checkbox', 'date', 'menu', 'multimenu', 'number', 'radiobutton', 'text', 'textarea', 'url' ); 398 399 $this->create_default_data_fields($fieldtypes, $data1); 400 401 $data1record1id = $this->create_default_data_record($data1); 402 403 $data1entry1 = $this->get_entry_for_id($data1record1id); 404 405 $data1doc = $searcharea->get_document($data1entry1); 406 407 $this->assertEquals($data1doc->get('courseid'), $course->id); 408 $this->assertEquals($data1doc->get('title'), 'text for testing'); 409 $this->assertEquals($data1doc->get('content'), 'menu1'); 410 $this->assertEquals($data1doc->get('description1'), 'radioopt1'); 411 $this->assertEquals($data1doc->get('description2'), 'opt1 opt2 opt3 opt4 multimenu1 multimenu2 multimenu3 multimenu4 text area testing http://example.url'); 412 413 // Second Case. 414 $data2 = $this->getDataGenerator()->create_module('data', $record); 415 416 $fieldtypes = array( 417 array('checkbox', 1), 418 array('textarea', 0), 419 array('menu', 0), 420 array('number', 1), 421 array('url', 0), 422 array('text', 0) 423 ); 424 425 $this->create_default_data_fields($fieldtypes, $data2); 426 427 $data2record1id = $this->create_default_data_record($data2); 428 429 $data2entry1 = $this->get_entry_for_id($data2record1id); 430 431 $data2doc = $searcharea->get_document($data2entry1); 432 433 $this->assertEquals($data2doc->get('courseid'), $course->id); 434 $this->assertEquals($data2doc->get('title'), 'opt1 opt2 opt3 opt4'); 435 $this->assertEquals($data2doc->get('content'), 'text for testing'); 436 $this->assertEquals($data2doc->get('description1'), 'menu1'); 437 $this->assertEquals($data2doc->get('description2'), 'text area testing http://example.url'); 438 439 // Third Case. 440 $data3 = $this->getDataGenerator()->create_module('data', $record); 441 442 $fieldtypes = array( 'url' ); 443 444 $this->create_default_data_fields($fieldtypes, $data3); 445 446 $data3record1id = $this->create_default_data_record($data3); 447 448 $data3entry1 = $this->get_entry_for_id($data3record1id); 449 450 $this->assertFalse($searcharea->get_document($data3entry1)); 451 452 // Fourth Case. 453 $data4 = $this->getDataGenerator()->create_module('data', $record); 454 455 $fieldtypes = array( array('date', 1), array('text', 1)); 456 457 $this->create_default_data_fields($fieldtypes, $data4); 458 459 $data4record1id = $this->create_default_data_record($data4); 460 461 $data4entry1 = $this->get_entry_for_id($data4record1id); 462 463 $this->assertFalse($searcharea->get_document($data4entry1)); 464 465 // Fifth Case. 466 $data5 = $this->getDataGenerator()->create_module('data', $record); 467 468 $fieldtypes = array( 469 array('checkbox', 0), 470 array('number', 1), 471 array('text', 0), 472 array('date', 1), 473 array('textarea', 0), 474 array('url', 1)); 475 476 $this->create_default_data_fields($fieldtypes, $data5); 477 478 $data5record1id = $this->create_default_data_record($data5); 479 480 $data5entry1 = $this->get_entry_for_id($data5record1id); 481 482 $data5doc = $searcharea->get_document($data5entry1); 483 484 $this->assertEquals($data5doc->get('courseid'), $course->id); 485 $this->assertEquals($data5doc->get('title'), 'http://example.url'); 486 $this->assertEquals($data5doc->get('content'), 'text for testing'); 487 $this->assertEquals($data5doc->get('description1'), 'opt1 opt2 opt3 opt4'); 488 $this->assertEquals($data5doc->get('description2'), 'text area testing'); 489 490 // Sixth Case. 491 $data6 = $this->getDataGenerator()->create_module('data', $record); 492 493 $fieldtypes = array( array('date', 1), array('number', 1)); 494 495 $this->create_default_data_fields($fieldtypes, $data6); 496 497 $data6record1id = $this->create_default_data_record($data6); 498 499 $data6entry1 = $this->get_entry_for_id($data6record1id); 500 501 $data6doc = $searcharea->get_document($data6entry1); 502 503 $this->assertFalse($data6doc); 504 505 // Seventh Case. 506 $data7 = $this->getDataGenerator()->create_module('data', $record); 507 508 $fieldtypes = array( array('date', 1), array('number', 1), 509 array('text', 0), array('textarea', 0)); 510 511 $this->create_default_data_fields($fieldtypes, $data7); 512 513 $data7record1id = $this->create_default_data_record($data7); 514 515 $data7entry1 = $this->get_entry_for_id($data7record1id); 516 517 $data7doc = $searcharea->get_document($data7entry1); 518 519 $this->assertEquals($data7doc->get('courseid'), $course->id); 520 $this->assertEquals($data7doc->get('title'), 'text for testing'); 521 $this->assertEquals($data7doc->get('content'), 'text area testing'); 522 523 // Eight Case. 524 $data8 = $this->getDataGenerator()->create_module('data', $record); 525 526 $fieldtypes = array('url', 'url', 'url', 'text'); 527 528 $this->create_default_data_fields($fieldtypes, $data8); 529 530 $data8record1id = $this->create_default_data_record($data8); 531 532 $data8entry1 = $this->get_entry_for_id($data8record1id); 533 534 $data8doc = $searcharea->get_document($data8entry1); 535 536 $this->assertEquals($data8doc->get('courseid'), $course->id); 537 $this->assertEquals($data8doc->get('title'), 'text for testing'); 538 $this->assertEquals($data8doc->get('content'), 'http://example.url'); 539 $this->assertEquals($data8doc->get('description1'), 'http://example.url'); 540 $this->assertEquals($data8doc->get('description2'), 'http://example.url'); 541 542 // Ninth Case. 543 $data9 = $this->getDataGenerator()->create_module('data', $record); 544 545 $fieldtypes = array('radiobutton', 'menu', 'multimenu'); 546 547 $this->create_default_data_fields($fieldtypes, $data9); 548 549 $data9record1id = $this->create_default_data_record($data9); 550 551 $data9entry1 = $this->get_entry_for_id($data9record1id); 552 553 $data9doc = $searcharea->get_document($data9entry1); 554 555 $this->assertEquals($data9doc->get('courseid'), $course->id); 556 $this->assertEquals($data9doc->get('title'), 'radioopt1'); 557 $this->assertEquals($data9doc->get('content'), 'menu1'); 558 $this->assertEquals($data9doc->get('description1'), 'multimenu1 multimenu2 multimenu3 multimenu4'); 559 560 // Tenth Case. 561 $data10 = $this->getDataGenerator()->create_module('data', $record); 562 563 $fieldtypes = array('checkbox', 'textarea', 'multimenu'); 564 565 $this->create_default_data_fields($fieldtypes, $data10); 566 567 $data10record1id = $this->create_default_data_record($data10); 568 569 $data10entry1 = $this->get_entry_for_id($data10record1id); 570 571 $data10doc = $searcharea->get_document($data10entry1); 572 573 $this->assertEquals($data10doc->get('courseid'), $course->id); 574 $this->assertEquals($data10doc->get('title'), 'opt1 opt2 opt3 opt4'); 575 $this->assertEquals($data10doc->get('content'), 'text area testing'); 576 $this->assertEquals($data10doc->get('description1'), 'multimenu1 multimenu2 multimenu3 multimenu4'); 577 578 } 579 580 /** 581 * Group support for data entries. 582 */ 583 public function test_data_entries_group_support() { 584 global $DB; 585 586 // Get the search area and test generators. 587 $searcharea = \core_search\manager::get_search_area($this->databaseentryareaid); 588 $generator = $this->getDataGenerator(); 589 $datagenerator = $generator->get_plugin_generator('mod_data'); 590 591 // Create a course, a user, and two groups. 592 $course = $generator->create_course(); 593 $user = $generator->create_user(); 594 $generator->enrol_user($user->id, $course->id, 'teacher'); 595 $group1 = $generator->create_group(['courseid' => $course->id]); 596 $group2 = $generator->create_group(['courseid' => $course->id]); 597 598 // Separate groups database. 599 $data = self::getDataGenerator()->create_module('data', ['course' => $course->id, 600 'groupmode' => SEPARATEGROUPS]); 601 $fieldtypes = ['text', 'textarea']; 602 $this->create_default_data_fields($fieldtypes, $data); 603 $fields = $DB->get_records('data_fields', array('dataid' => $data->id)); 604 foreach ($fields as $field) { 605 switch ($field->type) { 606 case 'text' : 607 $textid = $field->id; 608 break; 609 case 'textarea' : 610 $textareaid = $field->id; 611 break; 612 } 613 } 614 615 // As admin, create entries with each group and all groups. 616 $this->setAdminUser(); 617 $fieldvalues = [$textid => 'Title', $textareaid => 'Content']; 618 $e1 = $datagenerator->create_entry($data, $fieldvalues, $group1->id); 619 $e2 = $datagenerator->create_entry($data, $fieldvalues, $group2->id); 620 $e3 = $datagenerator->create_entry($data, $fieldvalues); 621 622 // Do the indexing of all 3 entries. 623 $rs = $searcharea->get_recordset_by_timestamp(0); 624 $results = []; 625 foreach ($rs as $rec) { 626 $results[$rec->id] = $rec; 627 } 628 $rs->close(); 629 $this->assertCount(3, $results); 630 631 // Check each has the correct groupid. 632 $doc = $searcharea->get_document($results[$e1]); 633 $this->assertTrue($doc->is_set('groupid')); 634 $this->assertEquals($group1->id, $doc->get('groupid')); 635 $doc = $searcharea->get_document($results[$e2]); 636 $this->assertTrue($doc->is_set('groupid')); 637 $this->assertEquals($group2->id, $doc->get('groupid')); 638 $doc = $searcharea->get_document($results[$e3]); 639 $this->assertFalse($doc->is_set('groupid')); 640 641 // While we're here, also test that the search area requests restriction by group. 642 $modinfo = get_fast_modinfo($course); 643 $this->assertTrue($searcharea->restrict_cm_access_by_group($modinfo->get_cm($data->cmid))); 644 645 // In visible groups mode, it won't request restriction by group. 646 set_coursemodule_groupmode($data->cmid, VISIBLEGROUPS); 647 $modinfo = get_fast_modinfo($course); 648 $this->assertFalse($searcharea->restrict_cm_access_by_group($modinfo->get_cm($data->cmid))); 649 } 650 651 /** 652 * Document accesses. 653 * 654 * @return void 655 */ 656 public function test_data_entries_access() { 657 global $DB; 658 659 // Returns the instance as long as the area is supported. 660 $searcharea = \core_search\manager::get_search_area($this->databaseentryareaid); 661 $this->assertInstanceOf('\mod_data\search\entry', $searcharea); 662 663 $user1 = self::getDataGenerator()->create_user(); 664 $user2 = self::getDataGenerator()->create_user(); 665 $user3 = self::getDataGenerator()->create_user(); 666 $userteacher1 = self::getDataGenerator()->create_user(); 667 668 $course1 = self::getDataGenerator()->create_course(); 669 $course2 = self::getDataGenerator()->create_course(); 670 671 $this->getDataGenerator()->enrol_user($user1->id, $course1->id, 'student'); 672 $this->getDataGenerator()->enrol_user($user2->id, $course1->id, 'student'); 673 $this->getDataGenerator()->enrol_user($userteacher1->id, $course1->id, 'teacher'); 674 675 $this->getDataGenerator()->enrol_user($user3->id, $course2->id, 'student'); 676 677 $record = new \stdClass(); 678 $record->course = $course1->id; 679 680 $this->setUser($userteacher1); 681 682 $data1 = $this->getDataGenerator()->create_module('data', $record); 683 684 $fieldtypes = array( 'checkbox', 'date', 'menu', 'multimenu', 'number', 'radiobutton', 'text', 'textarea', 'url' ); 685 686 $this->create_default_data_fields($fieldtypes, $data1); 687 688 $this->setUser($user1); 689 $data1record1id = $this->create_default_data_record($data1); 690 691 $this->assertEquals(\core_search\manager::ACCESS_GRANTED, $searcharea->check_access($data1record1id)); 692 $this->assertEquals(\core_search\manager::ACCESS_DELETED, $searcharea->check_access(-1)); 693 694 $this->setUser($user2); 695 $this->assertEquals(\core_search\manager::ACCESS_GRANTED, $searcharea->check_access($data1record1id)); 696 697 $this->setUser($user3); 698 $this->assertEquals(\core_search\manager::ACCESS_DENIED, $searcharea->check_access($data1record1id)); 699 700 $this->setUser($userteacher1); 701 $this->assertEquals(\core_search\manager::ACCESS_GRANTED, $searcharea->check_access($data1record1id)); 702 703 $this->setAdminUser(); 704 $this->assertEquals(\core_search\manager::ACCESS_GRANTED, $searcharea->check_access($data1record1id)); 705 706 $this->setGuestUser(); 707 $this->assertEquals(\core_search\manager::ACCESS_DENIED, $searcharea->check_access($data1record1id)); 708 709 // Case with groups. 710 $user1 = self::getDataGenerator()->create_user(); 711 $user2 = self::getDataGenerator()->create_user(); 712 $user3 = self::getDataGenerator()->create_user(); 713 $userteacher1 = self::getDataGenerator()->create_user(); 714 715 $course = self::getDataGenerator()->create_course(array('groupmode' => 1, 'groupmodeforce' => 1)); 716 717 $this->getDataGenerator()->enrol_user($user1->id, $course->id, 'student'); 718 $this->getDataGenerator()->enrol_user($user2->id, $course->id, 'student'); 719 $this->getDataGenerator()->enrol_user($userteacher1->id, $course->id, 'teacher'); 720 $this->getDataGenerator()->enrol_user($user3->id, $course->id, 'student'); 721 722 $groupa = $this->getDataGenerator()->create_group(array('courseid' => $course->id, 'name' => 'groupA')); 723 $groupb = $this->getDataGenerator()->create_group(array('courseid' => $course->id, 'name' => 'groupB')); 724 725 $this->getDataGenerator()->create_group_member(array('userid' => $user1->id, 'groupid' => $groupa->id)); 726 $this->getDataGenerator()->create_group_member(array('userid' => $user2->id, 'groupid' => $groupa->id)); 727 $this->getDataGenerator()->create_group_member(array('userid' => $userteacher1->id, 'groupid' => $groupa->id)); 728 729 $this->getDataGenerator()->create_group_member(array('userid' => $user3->id, 'groupid' => $groupb->id)); 730 731 $record = new \stdClass(); 732 $record->course = $course->id; 733 734 $this->setUser($userteacher1); 735 736 $data2 = $this->getDataGenerator()->create_module('data', $record); 737 738 $cm = get_coursemodule_from_instance('data', $data2->id, $course->id); 739 $cm->groupmode = '1'; 740 $cm->effectivegroupmode = '1'; 741 742 $fieldtypes = array( 'checkbox', 'date', 'menu', 'multimenu', 'number', 'radiobutton', 'text', 'textarea', 'url' ); 743 744 $this->create_default_data_fields($fieldtypes, $data2); 745 746 $this->setUser($user1); 747 748 $data2record1id = $this->create_default_data_record($data2, $groupa->id); 749 750 $this->assertEquals(\core_search\manager::ACCESS_GRANTED, $searcharea->check_access($data2record1id)); 751 $this->assertEquals(\core_search\manager::ACCESS_DELETED, $searcharea->check_access(-1)); 752 753 $this->setUser($user2); 754 $this->assertEquals(\core_search\manager::ACCESS_GRANTED, $searcharea->check_access($data2record1id)); 755 756 $this->setUser($user3); 757 $this->assertEquals(\core_search\manager::ACCESS_DENIED, $searcharea->check_access($data2record1id)); 758 759 $this->setUser($userteacher1); 760 $this->assertEquals(\core_search\manager::ACCESS_GRANTED, $searcharea->check_access($data2record1id)); 761 762 $this->setAdminUser(); 763 $this->assertEquals(\core_search\manager::ACCESS_GRANTED, $searcharea->check_access($data2record1id)); 764 765 $this->setGuestUser(); 766 $this->assertEquals(\core_search\manager::ACCESS_DENIED, $searcharea->check_access($data2record1id)); 767 768 // Case with approval. 769 $user1 = self::getDataGenerator()->create_user(); 770 $user2 = self::getDataGenerator()->create_user(); 771 $userteacher1 = self::getDataGenerator()->create_user(); 772 773 $course = self::getDataGenerator()->create_course(); 774 775 $this->getDataGenerator()->enrol_user($user1->id, $course->id, 'student'); 776 $this->getDataGenerator()->enrol_user($user2->id, $course->id, 'student'); 777 $this->getDataGenerator()->enrol_user($userteacher1->id, $course->id, 'teacher'); 778 779 $record = new \stdClass(); 780 $record->course = $course->id; 781 782 $this->setUser($userteacher1); 783 784 $data3 = $this->getDataGenerator()->create_module('data', $record); 785 786 $DB->update_record('data', array('id' => $data3->id, 'approval' => 1)); 787 788 $fieldtypes = array( 'checkbox', 'date', 'menu', 'multimenu', 'number', 'radiobutton', 'text', 'textarea', 'url' ); 789 790 $this->create_default_data_fields($fieldtypes, $data3); 791 792 $this->setUser($user1); 793 794 $data3record1id = $this->create_default_data_record($data3); 795 796 $this->assertEquals(\core_search\manager::ACCESS_GRANTED, $searcharea->check_access($data3record1id)); 797 $this->assertEquals(\core_search\manager::ACCESS_DELETED, $searcharea->check_access(-1)); 798 799 $this->setUser($user2); 800 $this->assertEquals(\core_search\manager::ACCESS_DENIED, $searcharea->check_access($data3record1id)); 801 802 $this->setUser($userteacher1); 803 $this->assertEquals(\core_search\manager::ACCESS_GRANTED, $searcharea->check_access($data3record1id)); 804 805 $this->setAdminUser(); 806 $this->assertEquals(\core_search\manager::ACCESS_GRANTED, $searcharea->check_access($data3record1id)); 807 808 $this->setGuestUser(); 809 $this->assertEquals(\core_search\manager::ACCESS_DENIED, $searcharea->check_access($data3record1id)); 810 811 $DB->update_record('data_records', array('id' => $data3record1id, 'approved' => 1)); 812 813 $this->setUser($user1); 814 $this->assertEquals(\core_search\manager::ACCESS_GRANTED, $searcharea->check_access($data3record1id)); 815 $this->assertEquals(\core_search\manager::ACCESS_DELETED, $searcharea->check_access(-1)); 816 817 $this->setUser($user2); 818 $this->assertEquals(\core_search\manager::ACCESS_GRANTED, $searcharea->check_access($data3record1id)); 819 820 $this->setUser($userteacher1); 821 $this->assertEquals(\core_search\manager::ACCESS_GRANTED, $searcharea->check_access($data3record1id)); 822 823 $this->setAdminUser(); 824 $this->assertEquals(\core_search\manager::ACCESS_GRANTED, $searcharea->check_access($data3record1id)); 825 826 $this->setGuestUser(); 827 $this->assertEquals(\core_search\manager::ACCESS_DENIED, $searcharea->check_access($data3record1id)); 828 829 // Case with requiredentriestoview. 830 $this->setAdminUser(); 831 832 $record->requiredentriestoview = 2; 833 834 $data4 = $this->getDataGenerator()->create_module('data', $record); 835 $fieldtypes = array( 'checkbox', 'date', 'menu', 'multimenu', 'number', 'radiobutton', 'text', 'textarea', 'url' ); 836 837 $this->create_default_data_fields($fieldtypes, $data4); 838 839 $data4record1id = $this->create_default_data_record($data4); 840 841 $this->setUser($user1); 842 $this->assertEquals(\core_search\manager::ACCESS_DENIED, $searcharea->check_access($data4record1id)); 843 844 $data4record2id = $this->create_default_data_record($data4); 845 $this->assertEquals(\core_search\manager::ACCESS_GRANTED, $searcharea->check_access($data4record1id)); 846 $this->assertEquals(\core_search\manager::ACCESS_GRANTED, $searcharea->check_access($data4record2id)); 847 } 848 849 /** 850 * Test for file contents. 851 * 852 * @return void 853 */ 854 public function test_attach_files() { 855 global $DB, $USER; 856 857 $fs = get_file_storage(); 858 859 // Returns the instance as long as the area is supported. 860 $searcharea = \core_search\manager::get_search_area($this->databaseentryareaid); 861 $this->assertInstanceOf('\mod_data\search\entry', $searcharea); 862 863 $user1 = self::getDataGenerator()->create_user(); 864 865 $course = self::getDataGenerator()->create_course(); 866 867 $this->getDataGenerator()->enrol_user($user1->id, $course->id, 'student'); 868 869 $record = new \stdClass(); 870 $record->course = $course->id; 871 872 $this->setAdminUser(); 873 874 // Creating database activity instance. 875 $data1 = $this->getDataGenerator()->create_module('data', $record); 876 877 // Creating file field. 878 $record = new \stdClass; 879 $record->type = 'file'; 880 $record->dataid = $data1->id; 881 $record->required = 0; 882 $record->name = 'FileFld'; 883 $record->description = 'Just another file field'; 884 $record->param3 = 0; 885 $record->param1 = ''; 886 $record->param2 = ''; 887 888 $data1filefieldid = $DB->insert_record('data_fields', $record); 889 890 // Creating text field. 891 $record = new \stdClass; 892 $record->type = 'text'; 893 $record->dataid = $data1->id; 894 $record->required = 0; 895 $record->name = 'TextFld'; 896 $record->description = 'Just another text field'; 897 $record->param3 = 0; 898 $record->param1 = ''; 899 $record->param2 = ''; 900 901 $data1textfieldid = $DB->insert_record('data_fields', $record); 902 903 // Creating textarea field. 904 $record = new \stdClass; 905 $record->type = 'textarea'; 906 $record->dataid = $data1->id; 907 $record->required = 0; 908 $record->name = 'TextAreaFld'; 909 $record->description = 'Just another textarea field'; 910 $record->param1 = ''; 911 $record->param2 = 60; 912 $record->param3 = 35; 913 $record->param3 = 1; 914 $record->param3 = 0; 915 916 $data1textareafieldid = $DB->insert_record('data_fields', $record); 917 918 // Creating 1st entry. 919 $record = new \stdClass; 920 $record->userid = $USER->id; 921 $record->dataid = $data1->id; 922 $record->groupid = 0; 923 924 $data1record1id = $DB->insert_record('data_records', $record); 925 926 $record = new \stdClass; 927 $record->fieldid = $data1filefieldid; 928 $record->recordid = $data1record1id; 929 $record->content = 'myfile1.txt'; 930 $data1contentfileid1 = $DB->insert_record('data_content', $record); 931 932 $filerecord = [ 933 'contextid' => \context_module::instance($data1->cmid)->id, 934 'component' => 'mod_data', 935 'filearea' => 'content', 936 'itemid' => $data1contentfileid1, 937 'filepath' => '/', 938 'filename' => 'myfile1.txt' 939 ]; 940 941 $data1record1file = $fs->create_file_from_string($filerecord, 'Some contents 1'); 942 943 $record = new \stdClass; 944 $record->fieldid = $data1textfieldid; 945 $record->recordid = $data1record1id; 946 $record->content = 'sample text'; 947 $DB->insert_record('data_content', $record); 948 949 $record = new \stdClass; 950 $record->fieldid = $data1textareafieldid; 951 $record->recordid = $data1record1id; 952 $record->content = '<br>sample text<p /><br/>'; 953 $record->content1 = 1; 954 $DB->insert_record('data_content', $record); 955 956 // Creating 2nd entry. 957 $record = new \stdClass; 958 $record->userid = $USER->id; 959 $record->dataid = $data1->id; 960 $record->groupid = 0; 961 $data1record2id = $DB->insert_record('data_records', $record); 962 963 $record = new \stdClass; 964 $record->fieldid = $data1filefieldid; 965 $record->recordid = $data1record2id; 966 $record->content = 'myfile2.txt'; 967 $data1contentfileid2 = $DB->insert_record('data_content', $record); 968 969 $filerecord['itemid'] = $data1contentfileid2; 970 $filerecord['filename'] = 'myfile2.txt'; 971 $data1record2file = $fs->create_file_from_string($filerecord, 'Some contents 2'); 972 973 $record = new \stdClass; 974 $record->fieldid = $data1textfieldid; 975 $record->recordid = $data1record2id; 976 $record->content = 'sample text'; 977 $DB->insert_record('data_content', $record); 978 979 $record = new \stdClass; 980 $record->fieldid = $data1textareafieldid; 981 $record->recordid = $data1record2id; 982 $record->content = '<br>sample text<p /><br/>'; 983 $record->content1 = 1; 984 $DB->insert_record('data_content', $record); 985 986 // Now get all the posts and see if they have the right files attached. 987 $searcharea = \core_search\manager::get_search_area($this->databaseentryareaid); 988 $recordset = $searcharea->get_recordset_by_timestamp(0); 989 $nrecords = 0; 990 foreach ($recordset as $record) { 991 $doc = $searcharea->get_document($record); 992 $searcharea->attach_files($doc); 993 $files = $doc->get_files(); 994 // Now check that each doc has the right files on it. 995 switch ($doc->get('itemid')) { 996 case ($data1record1id): 997 $this->assertCount(1, $files); 998 $this->assertEquals($data1record1file->get_id(), $files[$data1record1file->get_id()]->get_id()); 999 break; 1000 case ($data1record2id): 1001 $this->assertCount(1, $files); 1002 $this->assertEquals($data1record2file->get_id(), $files[$data1record2file->get_id()]->get_id()); 1003 break; 1004 default: 1005 $this->fail('Unexpected entry returned'); 1006 break; 1007 } 1008 $nrecords++; 1009 } 1010 $recordset->close(); 1011 $this->assertEquals(2, $nrecords); 1012 } 1013 1014 /** 1015 * Creates default fields for a database instance 1016 * 1017 * @param array $fieldtypes 1018 * @param mod_data $data 1019 * @return void 1020 */ 1021 protected function create_default_data_fields($fieldtypes, $data) { 1022 $count = 1; 1023 1024 // Creating test Fields with default parameter values. 1025 foreach ($fieldtypes as $fieldtype) { 1026 1027 // Creating variables dynamically. 1028 $fieldname = 'field-'.$count; 1029 $record = new \stdClass(); 1030 $record->name = $fieldname; 1031 1032 if (is_array($fieldtype)) { 1033 $record->type = $fieldtype[0]; 1034 $record->required = $fieldtype[1]; 1035 } else { 1036 $record->type = $fieldtype; 1037 $record->required = 0; 1038 } 1039 1040 ${$fieldname} = $this->getDataGenerator()->get_plugin_generator('mod_data')->create_field($record, $data); 1041 $count++; 1042 } 1043 } 1044 1045 /** 1046 * Creates default database entry content values for default field param values 1047 * 1048 * @param mod_data $data 1049 * @param int $groupid 1050 * @return int 1051 */ 1052 protected function create_default_data_record($data, $groupid = 0) { 1053 global $DB; 1054 1055 $fields = $DB->get_records('data_fields', array('dataid' => $data->id)); 1056 1057 $fieldcontents = array(); 1058 foreach ($fields as $fieldrecord) { 1059 switch ($fieldrecord->type) { 1060 case 'checkbox': 1061 $fieldcontents[$fieldrecord->id] = array('opt1', 'opt2', 'opt3', 'opt4'); 1062 break; 1063 1064 case 'multimenu': 1065 $fieldcontents[$fieldrecord->id] = array('multimenu1', 'multimenu2', 'multimenu3', 'multimenu4'); 1066 break; 1067 1068 case 'date': 1069 $fieldcontents[$fieldrecord->id] = '27-07-2016'; 1070 break; 1071 1072 case 'menu': 1073 $fieldcontents[$fieldrecord->id] = 'menu1'; 1074 break; 1075 1076 case 'radiobutton': 1077 $fieldcontents[$fieldrecord->id] = 'radioopt1'; 1078 break; 1079 1080 case 'number': 1081 $fieldcontents[$fieldrecord->id] = '12345'; 1082 break; 1083 1084 case 'text': 1085 $fieldcontents[$fieldrecord->id] = 'text for testing'; 1086 break; 1087 1088 case 'textarea': 1089 $fieldcontents[$fieldrecord->id] = '<p>text area testing<br /></p>'; 1090 break; 1091 1092 case 'url': 1093 $fieldcontents[$fieldrecord->id] = array('example.url', 'sampleurl'); 1094 break; 1095 1096 default: 1097 $this->fail('Unexpected field type'); 1098 break; 1099 } 1100 1101 } 1102 1103 return $this->getDataGenerator()->get_plugin_generator('mod_data')->create_entry($data, $fieldcontents, $groupid); 1104 } 1105 1106 /** 1107 * Creates default database entry content values for default field param values 1108 * 1109 * @param int $recordid 1110 * @return stdClass 1111 */ 1112 protected function get_entry_for_id($recordid ) { 1113 global $DB; 1114 1115 $sql = "SELECT dr.*, d.course 1116 FROM {data_records} dr 1117 JOIN {data} d ON d.id = dr.dataid 1118 WHERE dr.id = :drid"; 1119 return $DB->get_record_sql($sql, array('drid' => $recordid)); 1120 } 1121 1122 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body