MDL-35332: Use fast hash when generating hashes during tests
[moodle.git] / lib / testing / generator / data_generator.php
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/>.
17 /**
18  * Data generator.
19  *
20  * @package    core
21  * @category   test
22  * @copyright  2012 Petr Skoda {@link http://skodak.org}
23  * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
24  */
27 /**
28  * Data generator class for unit tests and other tools that need to create fake test sites.
29  *
30  * @package    core
31  * @category   test
32  * @copyright  2012 Petr Skoda {@link http://skodak.org}
33  * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
34  */
35 class testing_data_generator {
36     protected $usercounter = 0;
37     protected $categorycount = 0;
38     protected $cohortcount = 0;
39     protected $coursecount = 0;
40     protected $scalecount = 0;
41     protected $groupcount = 0;
42     protected $groupingcount = 0;
44     /**
45      * @var int keep track of how many forum discussions have been created.
46      */
47     protected $forumdiscussioncount = 0;
49     /**
50      * @var int keep track of how many forum posts have been created.
51      */
52     protected $forumpostcount = 0;
54     /** @var array list of plugin generators */
55     protected $generators = array();
57     /** @var array lis of common last names */
58     public $lastnames = array(
59         'Smith', 'Johnson', 'Williams', 'Brown', 'Jones', 'Miller', 'Davis', 'García', 'Rodríguez', 'Wilson',
60         'Müller', 'Schmidt', 'Schneider', 'Fischer', 'Meyer', 'Weber', 'Schulz', 'Wagner', 'Becker', 'Hoffmann',
61         'Novák', 'Svoboda', 'Novotný', 'Dvořák', 'Černý', 'Procházková', 'Kučerová', 'Veselá', 'Horáková', 'Němcová',
62         'Смирнов', 'Иванов', 'Кузнецов', 'Соколов', 'Попов', 'Лебедева', 'Козлова', 'Новикова', 'Морозова', 'Петрова',
63         '王', '李', '张', '刘', '陈', '楊', '黃', '趙', '吳', '周',
64         '佐藤', '鈴木', '高橋', '田中', '渡辺', '伊藤', '山本', '中村', '小林', '斎藤',
65     );
67     /** @var array lis of common first names */
68     public $firstnames = array(
69         'Jacob', 'Ethan', 'Michael', 'Jayden', 'William', 'Isabella', 'Sophia', 'Emma', 'Olivia', 'Ava',
70         'Lukas', 'Leon', 'Luca', 'Timm', 'Paul', 'Leonie', 'Leah', 'Lena', 'Hanna', 'Laura',
71         'Jakub', 'Jan', 'Tomáš', 'Lukáš', 'Matěj', 'Tereza', 'Eliška', 'Anna', 'Adéla', 'Karolína',
72         'Даниил', 'Максим', 'Артем', 'Иван', 'Александр', 'София', 'Анастасия', 'Дарья', 'Мария', 'Полина',
73         '伟', '伟', '芳', '伟', '秀英', '秀英', '娜', '秀英', '伟', '敏',
74         '翔', '大翔', '拓海', '翔太', '颯太', '陽菜', 'さくら', '美咲', '葵', '美羽',
75     );
77     public $loremipsum = <<<EOD
78 Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Nulla non arcu lacinia neque faucibus fringilla. Vivamus porttitor turpis ac leo. Integer in sapien. Nullam eget nisl. Aliquam erat volutpat. Cras elementum. Mauris suscipit, ligula sit amet pharetra semper, nibh ante cursus purus, vel sagittis velit mauris vel metus. Integer malesuada. Nullam lectus justo, vulputate eget mollis sed, tempor sed magna. Mauris elementum mauris vitae tortor. Aliquam erat volutpat.
79 Temporibus autem quibusdam et aut officiis debitis aut rerum necessitatibus saepe eveniet ut et voluptates repudiandae sint et molestiae non recusandae. Pellentesque ipsum. Cras pede libero, dapibus nec, pretium sit amet, tempor quis. Aliquam ante. Proin in tellus sit amet nibh dignissim sagittis. Vivamus porttitor turpis ac leo. Duis bibendum, lectus ut viverra rhoncus, dolor nunc faucibus libero, eget facilisis enim ipsum id lacus. In sem justo, commodo ut, suscipit at, pharetra vitae, orci. Aliquam erat volutpat. Nulla est.
80 Vivamus luctus egestas leo. Aenean fermentum risus id tortor. Mauris dictum facilisis augue. Aliquam erat volutpat. Aliquam ornare wisi eu metus. Aliquam id dolor. Duis condimentum augue id magna semper rutrum. Donec iaculis gravida nulla. Pellentesque ipsum. Etiam dictum tincidunt diam. Quisque tincidunt scelerisque libero. Etiam egestas wisi a erat.
81 Integer lacinia. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Mauris tincidunt sem sed arcu. Nullam feugiat, turpis at pulvinar vulputate, erat libero tristique tellus, nec bibendum odio risus sit amet ante. Aliquam id dolor. Maecenas sollicitudin. Et harum quidem rerum facilis est et expedita distinctio. Mauris suscipit, ligula sit amet pharetra semper, nibh ante cursus purus, vel sagittis velit mauris vel metus. Nullam dapibus fermentum ipsum. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugit, sed quia consequuntur magni dolores eos qui ratione voluptatem sequi nesciunt. Pellentesque sapien. Duis risus. Mauris elementum mauris vitae tortor. Suspendisse nisl. Integer rutrum, orci vestibulum ullamcorper ultricies, lacus quam ultricies odio, vitae placerat pede sem sit amet enim.
82 In laoreet, magna id viverra tincidunt, sem odio bibendum justo, vel imperdiet sapien wisi sed libero. Proin pede metus, vulputate nec, fermentum fringilla, vehicula vitae, justo. Nullam justo enim, consectetuer nec, ullamcorper ac, vestibulum in, elit. Quis autem vel eum iure reprehenderit qui in ea voluptate velit esse quam nihil molestiae consequatur, vel illum qui dolorem eum fugiat quo voluptas nulla pariatur? Maecenas lorem. Etiam posuere lacus quis dolor. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos hymenaeos. Curabitur ligula sapien, pulvinar a vestibulum quis, facilisis vel sapien. Nam sed tellus id magna elementum tincidunt. Suspendisse nisl. Vivamus luctus egestas leo. Nulla non arcu lacinia neque faucibus fringilla. Etiam dui sem, fermentum vitae, sagittis id, malesuada in, quam. Etiam dictum tincidunt diam. Etiam commodo dui eget wisi. Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugit, sed quia consequuntur magni dolores eos qui ratione voluptatem sequi nesciunt. Proin pede metus, vulputate nec, fermentum fringilla, vehicula vitae, justo. Duis ante orci, molestie vitae vehicula venenatis, tincidunt ac pede. Pellentesque sapien.
83 EOD;
85     /**
86      * To be called from data reset code only,
87      * do not use in tests.
88      * @return void
89      */
90     public function reset() {
91         $this->usercounter = 0;
92         $this->categorycount = 0;
93         $this->coursecount = 0;
94         $this->scalecount = 0;
95         $this->forumdiscussioncount = 0;
96         $this->forumpostcount = 0;
98         foreach ($this->generators as $generator) {
99             $generator->reset();
100         }
101     }
103     /**
104      * Return generator for given plugin
105      * @param string $component
106      * @return mixed plugin data generator
107      */
108     public function get_plugin_generator($component) {
109         list($type, $plugin) = normalize_component($component);
111         if ($type !== 'mod' and $type !== 'block') {
112             throw new coding_exception("Plugin type $type does not support generators yet");
113         }
115         $dir = get_plugin_directory($type, $plugin);
117         if (!isset($this->generators[$type.'_'.$plugin])) {
118             $lib = "$dir/tests/generator/lib.php";
119             if (!include_once($lib)) {
120                 throw new coding_exception("Plugin $component does not support data generator, missing tests/generator/lib");
121             }
122             $classname = $type.'_'.$plugin.'_generator';
123             $this->generators[$type.'_'.$plugin] = new $classname($this);
124         }
126         return $this->generators[$type.'_'.$plugin];
127     }
129     /**
130      * Create a test user
131      * @param array|stdClass $record
132      * @param array $options
133      * @return stdClass user record
134      */
135     public function create_user($record=null, array $options=null) {
136         global $DB, $CFG;
138         $this->usercounter++;
139         $i = $this->usercounter;
141         $record = (array)$record;
143         if (!isset($record['auth'])) {
144             $record['auth'] = 'manual';
145         }
147         if (!isset($record['firstname']) and !isset($record['lastname'])) {
148             $country = rand(0, 5);
149             $firstname = rand(0, 4);
150             $lastname = rand(0, 4);
151             $female = rand(0, 1);
152             $record['firstname'] = $this->firstnames[($country*10) + $firstname + ($female*5)];
153             $record['lastname'] = $this->lastnames[($country*10) + $lastname + ($female*5)];
155         } else if (!isset($record['firstname'])) {
156             $record['firstname'] = 'Firstname'.$i;
158         } else if (!isset($record['lastname'])) {
159             $record['lastname'] = 'Lastname'.$i;
160         }
162         if (!isset($record['idnumber'])) {
163             $record['idnumber'] = '';
164         }
166         if (!isset($record['mnethostid'])) {
167             $record['mnethostid'] = $CFG->mnet_localhost_id;
168         }
170         if (!isset($record['username'])) {
171             $record['username'] = 'username'.$i;
172             $j = 2;
173             while ($DB->record_exists('user', array('username'=>$record['username'], 'mnethostid'=>$record['mnethostid']))) {
174                 $record['username'] = 'username'.$i.'_'.$j;
175                 $j++;
176             }
177         }
179         if (!isset($record['password'])) {
180             $record['password'] = 'lala';
181         }
183         if (!isset($record['email'])) {
184             $record['email'] = $record['username'].'@example.com';
185         }
187         if (!isset($record['confirmed'])) {
188             $record['confirmed'] = 1;
189         }
191         if (!isset($record['lang'])) {
192             $record['lang'] = 'en';
193         }
195         if (!isset($record['maildisplay'])) {
196             $record['maildisplay'] = 1;
197         }
199         if (!isset($record['deleted'])) {
200             $record['deleted'] = 0;
201         }
203         $record['timecreated'] = time();
204         $record['timemodified'] = $record['timecreated'];
205         $record['lastip'] = '0.0.0.0';
207         // Use fast hash during testing.
208         $record['password'] = hash_internal_user_password($record['password'], true);
210         if ($record['deleted']) {
211             $delname = $record['email'].'.'.time();
212             while ($DB->record_exists('user', array('username'=>$delname))) {
213                 $delname++;
214             }
215             $record['idnumber'] = '';
216             $record['email']    = md5($record['username']);
217             $record['username'] = $delname;
218             $record['picture']  = 0;
219         }
221         $userid = $DB->insert_record('user', $record);
223         if (!$record['deleted']) {
224             context_user::instance($userid);
225         }
227         return $DB->get_record('user', array('id'=>$userid), '*', MUST_EXIST);
228     }
230     /**
231      * Create a test course category
232      * @param array|stdClass $record
233      * @param array $options
234      * @return stdClass course category record
235      */
236     public function create_category($record=null, array $options=null) {
237         global $DB, $CFG;
238         require_once("$CFG->dirroot/course/lib.php");
240         $this->categorycount++;
241         $i = $this->categorycount;
243         $record = (array)$record;
245         if (!isset($record['name'])) {
246             $record['name'] = 'Course category '.$i;
247         }
249         if (!isset($record['idnumber'])) {
250             $record['idnumber'] = '';
251         }
253         if (!isset($record['description'])) {
254             $record['description'] = "Test course category $i\n$this->loremipsum";
255         }
257         if (!isset($record['descriptionformat'])) {
258             $record['descriptionformat'] = FORMAT_MOODLE;
259         }
261         if (!isset($record['parent'])) {
262             $record['parent'] = 0;
263         }
265         if (empty($record['parent'])) {
266             $parent = new stdClass();
267             $parent->path = '';
268             $parent->depth = 0;
269         } else {
270             $parent = $DB->get_record('course_categories', array('id'=>$record['parent']), '*', MUST_EXIST);
271         }
272         $record['depth'] = $parent->depth+1;
274         $record['sortorder'] = 0;
275         $record['timemodified'] = time();
276         $record['timecreated'] = $record['timemodified'];
278         $catid = $DB->insert_record('course_categories', $record);
279         $path = $parent->path . '/' . $catid;
280         $DB->set_field('course_categories', 'path', $path, array('id'=>$catid));
281         context_coursecat::instance($catid);
283         fix_course_sortorder();
285         return $DB->get_record('course_categories', array('id'=>$catid), '*', MUST_EXIST);
286     }
288     /**
289      * Create test cohort.
290      * @param array|stdClass $record
291      * @param array $options
292      * @return stdClass cohort record
293      */
294     public function create_cohort($record=null, array $options=null) {
295         global $DB, $CFG;
296         require_once("$CFG->dirroot/cohort/lib.php");
298         $this->cohortcount++;
299         $i = $this->cohortcount;
301         $record = (array)$record;
303         if (!isset($record['contextid'])) {
304             $record['contextid'] = context_system::instance()->id;
305         }
307         if (!isset($record['name'])) {
308             $record['name'] = 'Cohort '.$i;
309         }
311         if (!isset($record['idnumber'])) {
312             $record['idnumber'] = '';
313         }
315         if (!isset($record['description'])) {
316             $record['description'] = "Test cohort $i\n$this->loremipsum";
317         }
319         if (!isset($record['descriptionformat'])) {
320             $record['descriptionformat'] = FORMAT_MOODLE;
321         }
323         if (!isset($record['component'])) {
324             $record['component'] = '';
325         }
327         $id = cohort_add_cohort((object)$record);
329         return $DB->get_record('cohort', array('id'=>$id), '*', MUST_EXIST);
330     }
332     /**
333      * Create a test course
334      * @param array|stdClass $record
335      * @param array $options with keys:
336      *      'createsections'=>bool precreate all sections
337      * @return stdClass course record
338      */
339     public function create_course($record=null, array $options=null) {
340         global $DB, $CFG;
341         require_once("$CFG->dirroot/course/lib.php");
343         $this->coursecount++;
344         $i = $this->coursecount;
346         $record = (array)$record;
348         if (!isset($record['fullname'])) {
349             $record['fullname'] = 'Test course '.$i;
350         }
352         if (!isset($record['shortname'])) {
353             $record['shortname'] = 'tc_'.$i;
354         }
356         if (!isset($record['idnumber'])) {
357             $record['idnumber'] = '';
358         }
360         if (!isset($record['format'])) {
361             $record['format'] = 'topics';
362         }
364         if (!isset($record['newsitems'])) {
365             $record['newsitems'] = 0;
366         }
368         if (!isset($record['numsections'])) {
369             $record['numsections'] = 5;
370         }
372         if (!isset($record['summary'])) {
373             $record['summary'] = "Test course $i\n$this->loremipsum";
374         }
376         if (!isset($record['summaryformat'])) {
377             $record['summaryformat'] = FORMAT_MOODLE;
378         }
380         if (!isset($record['category'])) {
381             $record['category'] = $DB->get_field_select('course_categories', "MIN(id)", "parent=0");
382         }
384         $course = create_course((object)$record);
385         context_course::instance($course->id);
386         if (!empty($options['createsections'])) {
387             if (isset($course->numsections)) {
388                 course_create_sections_if_missing($course, range(0, $course->numsections));
389             } else {
390                 course_create_sections_if_missing($course, 0);
391             }
392         }
394         return $course;
395     }
397     /**
398      * Create course section if does not exist yet
399      * @param array|stdClass $record must contain 'course' and 'section' attributes
400      * @param array|null $options
401      * @return stdClass
402      * @throws coding_exception
403      */
404     public function create_course_section($record = null, array $options = null) {
405         global $DB;
407         $record = (array)$record;
409         if (empty($record['course'])) {
410             throw new coding_exception('course must be present in testing_data_generator::create_course_section() $record');
411         }
413         if (!isset($record['section'])) {
414             throw new coding_exception('section must be present in testing_data_generator::create_course_section() $record');
415         }
417         course_create_sections_if_missing($record['course'], $record['section']);
418         return get_fast_modinfo($record['course'])->get_section_info($record['section']);
419     }
421     /**
422      * Create a test block
423      * @param string $blockname
424      * @param array|stdClass $record
425      * @param array $options
426      * @return stdClass block instance record
427      */
428     public function create_block($blockname, $record=null, array $options=null) {
429         $generator = $this->get_plugin_generator('block_'.$blockname);
430         return $generator->create_instance($record, $options);
431     }
433     /**
434      * Create a test module
435      * @param string $modulename
436      * @param array|stdClass $record
437      * @param array $options
438      * @return stdClass activity record
439      */
440     public function create_module($modulename, $record=null, array $options=null) {
441         $generator = $this->get_plugin_generator('mod_'.$modulename);
442         return $generator->create_instance($record, $options);
443     }
445     /**
446      * Create a test group for the specified course
447      *
448      * $record should be either an array or a stdClass containing infomation about the group to create.
449      * At the very least it needs to contain courseid.
450      * Default values are added for name, description, and descriptionformat if they are not present.
451      *
452      * This function calls groups_create_group() to create the group within the database.
453      * @see groups_create_group
454      * @param array|stdClass $record
455      * @return stdClass group record
456      */
457     public function create_group($record) {
458         global $DB, $CFG;
460         require_once($CFG->dirroot . '/group/lib.php');
462         $this->groupcount++;
463         $i = $this->groupcount;
465         $record = (array)$record;
467         if (empty($record['courseid'])) {
468             throw new coding_exception('courseid must be present in testing_data_generator::create_group() $record');
469         }
471         if (!isset($record['name'])) {
472             $record['name'] = 'group-' . $i;
473         }
475         if (!isset($record['description'])) {
476             $record['description'] = "Test Group $i\n{$this->loremipsum}";
477         }
479         if (!isset($record['descriptionformat'])) {
480             $record['descriptionformat'] = FORMAT_MOODLE;
481         }
483         $id = groups_create_group((object)$record);
485         return $DB->get_record('groups', array('id'=>$id));
486     }
488     /**
489      * Create a test group member
490      * @param array|stdClass $record
491      * @throws coding_exception
492      * @return boolean
493      */
494     public function create_group_member($record) {
495         global $DB, $CFG;
497         require_once($CFG->dirroot . '/group/lib.php');
499         $record = (array)$record;
501         if (empty($record['userid'])) {
502             throw new coding_exception('user must be present in testing_util::create_group_member() $record');
503         }
505         if (!isset($record['groupid'])) {
506             throw new coding_exception('group must be present in testing_util::create_group_member() $record');
507         }
509         if (!isset($record['component'])) {
510             $record['component'] = null;
511         }
512         if (!isset($record['itemid'])) {
513             $record['itemid'] = 0;
514         }
516         return groups_add_member($record['groupid'], $record['userid'], $record['component'], $record['itemid']);
517     }
519     /**
520      * Create a test grouping for the specified course
521      *
522      * $record should be either an array or a stdClass containing infomation about the grouping to create.
523      * At the very least it needs to contain courseid.
524      * Default values are added for name, description, and descriptionformat if they are not present.
525      *
526      * This function calls groups_create_grouping() to create the grouping within the database.
527      * @see groups_create_grouping
528      * @param array|stdClass $record
529      * @return stdClass grouping record
530      */
531     public function create_grouping($record) {
532         global $DB, $CFG;
534         require_once($CFG->dirroot . '/group/lib.php');
536         $this->groupingcount++;
537         $i = $this->groupingcount;
539         $record = (array)$record;
541         if (empty($record['courseid'])) {
542             throw new coding_exception('courseid must be present in testing_data_generator::create_grouping() $record');
543         }
545         if (!isset($record['name'])) {
546             $record['name'] = 'grouping-' . $i;
547         }
549         if (!isset($record['description'])) {
550             $record['description'] = "Test Grouping $i\n{$this->loremipsum}";
551         }
553         if (!isset($record['descriptionformat'])) {
554             $record['descriptionformat'] = FORMAT_MOODLE;
555         }
557         $id = groups_create_grouping((object)$record);
559         return $DB->get_record('groupings', array('id'=>$id));
560     }
562     /**
563      * Create a test grouping group
564      * @param array|stdClass $record
565      * @throws coding_exception
566      * @return boolean
567      */
568     public function create_grouping_group($record) {
569         global $DB, $CFG;
571         require_once($CFG->dirroot . '/group/lib.php');
573         $record = (array)$record;
575         if (empty($record['groupingid'])) {
576             throw new coding_exception('grouping must be present in testing::create_grouping_group() $record');
577         }
579         if (!isset($record['groupid'])) {
580             throw new coding_exception('group must be present in testing_util::create_grouping_group() $record');
581         }
583         return groups_assign_grouping($record['groupingid'], $record['groupid']);
584     }
586     /**
587      * Create a test scale
588      * @param array|stdClass $record
589      * @param array $options
590      * @return stdClass block instance record
591      */
592     public function create_scale($record=null, array $options=null) {
593         global $DB;
595         $this->scalecount++;
596         $i = $this->scalecount;
598         $record = (array)$record;
600         if (!isset($record['name'])) {
601             $record['name'] = 'Test scale '.$i;
602         }
604         if (!isset($record['scale'])) {
605             $record['scale'] = 'A,B,C,D,F';
606         }
608         if (!isset($record['courseid'])) {
609             $record['courseid'] = 0;
610         }
612         if (!isset($record['userid'])) {
613             $record['userid'] = 0;
614         }
616         if (!isset($record['description'])) {
617             $record['description'] = 'Test scale description '.$i;
618         }
620         if (!isset($record['descriptionformat'])) {
621             $record['descriptionformat'] = FORMAT_MOODLE;
622         }
624         $record['timemodified'] = time();
626         if (isset($record['id'])) {
627             $DB->import_record('scale', $record);
628             $DB->get_manager()->reset_sequence('scale');
629             $id = $record['id'];
630         } else {
631             $id = $DB->insert_record('scale', $record);
632         }
634         return $DB->get_record('scale', array('id'=>$id), '*', MUST_EXIST);
635     }
637     /**
638      * Simplified enrolment of user to course using default options.
639      *
640      * It is strongly recommended to use only this method for 'manual' and 'self' plugins only!!!
641      *
642      * @param int $userid
643      * @param int $courseid
644      * @param int $roleid optional role id, use only with manual plugin
645      * @param string $enrol name of enrol plugin,
646      *     there must be exactly one instance in course,
647      *     it must support enrol_user() method.
648      * @return bool success
649      */
650     public function enrol_user($userid, $courseid, $roleid = null, $enrol = 'manual') {
651         global $DB;
653         if (!$plugin = enrol_get_plugin($enrol)) {
654             return false;
655         }
657         $instances = $DB->get_records('enrol', array('courseid'=>$courseid, 'enrol'=>$enrol));
658         if (count($instances) != 1) {
659             return false;
660         }
661         $instance = reset($instances);
663         if (is_null($roleid) and $instance->roleid) {
664             $roleid = $instance->roleid;
665         }
667         $plugin->enrol_user($instance, $userid, $roleid);
669         return true;
670     }
672     /**
673      * Function to create a dummy discussion.
674      *
675      * @param array|stdClass $record
676      * @return stdClass the discussion object
677      */
678     public function create_forum_discussion($record = null) {
679         global $DB;
681         // Increment the forum discussion count.
682         $this->forumdiscussioncount++;
684         $record = (array) $record;
686         if (!isset($record['course'])) {
687             throw new coding_exception('course must be present in phpunit_util::create_forum_discussion() $record');
688         }
690         if (!isset($record['forum'])) {
691             throw new coding_exception('forum must be present in phpunit_util::create_forum_discussion() $record');
692         }
694         if (!isset($record['userid'])) {
695             throw new coding_exception('userid must be present in phpunit_util::create_forum_discussion() $record');
696         }
698         if (!isset($record['name'])) {
699             $record['name'] = "Discussion " . $this->forumdiscussioncount;
700         }
702         if (!isset($record['subject'])) {
703             $record['subject'] = "Subject for discussion " . $this->forumdiscussioncount;
704         }
706         if (!isset($record['message'])) {
707             $record['message'] = html_writer::tag('p', 'Message for discussion ' . $this->forumdiscussioncount);
708         }
710         if (!isset($record['messageformat'])) {
711             $record['messageformat'] = editors_get_preferred_format();
712         }
714         if (!isset($record['messagetrust'])) {
715             $record['messagetrust'] = "";
716         }
718         if (!isset($record['assessed'])) {
719             $record['assessed'] = '1';
720         }
722         if (!isset($record['groupid'])) {
723             $record['groupid'] = "-1";
724         }
726         if (!isset($record['timestart'])) {
727             $record['timestart'] = "0";
728         }
730         if (!isset($record['timeend'])) {
731             $record['timeend'] = "0";
732         }
734         if (!isset($record['mailnow'])) {
735             $record['mailnow'] = "0";
736         }
738         $record = (object) $record;
740         // Add the discussion.
741         $record->id = forum_add_discussion($record, null, null, $record->userid);
743         return $record;
744     }
746     /**
747      * Function to create a dummy post.
748      *
749      * @param array|stdClass $record
750      * @return stdClass the post object
751      */
752     public function create_forum_post($record = null) {
753         global $DB;
755         // Increment the forum post count.
756         $this->forumpostcount++;
758         // Variable to store time.
759         $time = time() + $this->forumpostcount;
761         $record = (array) $record;
763         if (!isset($record['discussion'])) {
764             throw new coding_exception('discussion must be present in phpunit_util::create_forum_post() $record');
765         }
767         if (!isset($record['userid'])) {
768             throw new coding_exception('userid must be present in phpunit_util::create_forum_post() $record');
769         }
771         if (!isset($record['parent'])) {
772             $record['parent'] = 0;
773         }
775         if (!isset($record['subject'])) {
776             $record['subject'] = 'Forum post subject ' . $this->forumpostcount;
777         }
779         if (!isset($record['message'])) {
780             $record['message'] = html_writer::tag('p', 'Forum message post ' . $this->forumpostcount);
781         }
783         if (!isset($record['created'])) {
784             $record['created'] = $time;
785         }
787         if (!isset($record['modified'])) {
788             $record['modified'] = $time;
789         }
791         $record = (object) $record;
793         // Add the post.
794         $record->id = $DB->insert_record('forum_posts', $record);
796         // Update the last post.
797         forum_discussion_update_last_post($record->discussion);
799         return $record;
800     }
803 /**
804  * Deprecated in favour of testing_data_generator
805  *
806  * @deprecated since Moodle 2.5 MDL-37457 - please do not use this function any more.
807  * @todo       MDL-37517 This will be deleted in Moodle 2.7
808  * @see        testing_data_generator
809  * @package    core
810  * @category   test
811  * @copyright  2012 David Monllaó
812  * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
813  */
814 class phpunit_data_generator extends testing_data_generator {
816     /**
817      * Dumb constructor to throw the deprecated notification
818      */
819     public function __construct() {
820         debugging('Class phpunit_data_generator is deprecated, please use class testing_module_generator instead', DEBUG_DEVELOPER);
821     }