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