a9b944ec28456d9dc36ca470b564e6f2136a725a
[moodle.git] / lib / tests / phpunit_test.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  * PHPUnit integration unit tests
19  *
20  * @package    core
21  * @category   phpunit
22  * @copyright  2012 Petr Skoda {@link http://skodak.org}
23  * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
24  */
26 defined('MOODLE_INTERNAL') || die();
29 /**
30  * Test basic_testcase extra features and PHPUnit Moodle integration.
31  *
32  * @package    core
33  * @category   phpunit
34  * @copyright  2012 Petr Skoda {@link http://skodak.org}
35  * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
36  */
37 class core_phpunit_basic_testcase extends basic_testcase {
39     /**
40      * Tests that bootstrapping has occurred correctly
41      * @return void
42      */
43     public function test_bootstrap() {
44         global $CFG;
45         $this->assertTrue(isset($CFG->httpswwwroot));
46         $this->assertEquals($CFG->httpswwwroot, $CFG->wwwroot);
47         $this->assertEquals($CFG->prefix, $CFG->phpunit_prefix);
48     }
50     /**
51      * This is just a verification if I understand the PHPUnit assert docs right --skodak
52      * @return void
53      */
54     public function test_assert_behaviour() {
55         // arrays
56         $a = array('a', 'b', 'c');
57         $b = array('a', 'c', 'b');
58         $c = array('a', 'b', 'c');
59         $d = array('a', 'b', 'C');
60         $this->assertNotEquals($a, $b);
61         $this->assertNotEquals($a, $d);
62         $this->assertEquals($a, $c);
63         $this->assertEquals($a, $b, '', 0, 10, true);
65         // objects
66         $a = new stdClass();
67         $a->x = 'x';
68         $a->y = 'y';
69         $b = new stdClass(); // switched order
70         $b->y = 'y';
71         $b->x = 'x';
72         $c = $a;
73         $d = new stdClass();
74         $d->x = 'x';
75         $d->y = 'y';
76         $d->z = 'z';
77         $this->assertEquals($a, $b);
78         $this->assertNotSame($a, $b);
79         $this->assertEquals($a, $c);
80         $this->assertSame($a, $c);
81         $this->assertNotEquals($a, $d);
83         // string comparison
84         $this->assertEquals(1, '1');
85         $this->assertEquals(null, '');
87         $this->assertNotEquals(1, '1 ');
88         $this->assertNotEquals(0, '');
89         $this->assertNotEquals(null, '0');
90         $this->assertNotEquals(array(), '');
92         // other comparison
93         $this->assertEquals(null, null);
94         $this->assertEquals(false, null);
95         $this->assertEquals(0, null);
97         // emptiness
98         $this->assertEmpty(0);
99         $this->assertEmpty(0.0);
100         $this->assertEmpty('');
101         $this->assertEmpty('0');
102         $this->assertEmpty(false);
103         $this->assertEmpty(null);
104         $this->assertEmpty(array());
106         $this->assertNotEmpty(1);
107         $this->assertNotEmpty(0.1);
108         $this->assertNotEmpty(-1);
109         $this->assertNotEmpty(' ');
110         $this->assertNotEmpty('0 ');
111         $this->assertNotEmpty(true);
112         $this->assertNotEmpty(array(null));
113         $this->assertNotEmpty(new stdClass());
114     }
116 // Uncomment following tests to see logging of unexpected changes in global state and database
117 /*
118     public function test_db_modification() {
119         global $DB;
120         $DB->set_field('user', 'confirmed', 1, array('id'=>-1));
121     }
123     public function test_cfg_modification() {
124         global $CFG;
125         $CFG->xx = 'yy';
126         unset($CFG->admin);
127         $CFG->rolesactive = 0;
128     }
130     public function test_user_modification() {
131         global $USER;
132         $USER->id = 10;
133     }
135     public function test_course_modification() {
136         global $COURSE;
137         $COURSE->id = 10;
138     }
140     public function test_all_modifications() {
141         global $DB, $CFG, $USER, $COURSE;
142         $DB->set_field('user', 'confirmed', 1, array('id'=>-1));
143         $CFG->xx = 'yy';
144         unset($CFG->admin);
145         $CFG->rolesactive = 0;
146         $USER->id = 10;
147         $COURSE->id = 10;
148     }
150     public function test_transaction_problem() {
151         global $DB;
152         $DB->start_delegated_transaction();
153     }
154 */
158 /**
159  * Test advanced_testcase extra features.
160  *
161  * @package    core
162  * @category   phpunit
163  * @copyright  2012 Petr Skoda {@link http://skodak.org}
164  * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
165  */
166 class core_phpunit_advanced_testcase extends advanced_testcase {
168     public function test_set_user() {
169         global $USER, $DB;
171         $this->assertEquals(0, $USER->id);
172         $this->assertSame($_SESSION['USER'], $USER);
174         $user = $DB->get_record('user', array('id'=>2));
175         $this->setUser($user);
176         $this->assertEquals(2, $USER->id);
177         $this->assertEquals(2, $_SESSION['USER']->id);
178         $this->assertSame($_SESSION['USER'], $USER);
180         $USER->id = 3;
181         $this->assertEquals(3, $USER->id);
182         $this->assertEquals(3, $_SESSION['USER']->id);
183         $this->assertSame($_SESSION['USER'], $USER);
185         session_set_user($user);
186         $this->assertEquals(2, $USER->id);
187         $this->assertEquals(2, $_SESSION['USER']->id);
188         $this->assertSame($_SESSION['USER'], $USER);
190         $USER = $DB->get_record('user', array('id'=>1));
191         $this->assertEquals(1, $USER->id);
192         $this->assertEquals(1, $_SESSION['USER']->id);
193         $this->assertSame($_SESSION['USER'], $USER);
195         $this->setUser(null);
196         $this->assertEquals(0, $USER->id);
197         $this->assertSame($_SESSION['USER'], $USER);
198     }
200     public function test_database_reset() {
201         global $DB;
203         $this->resetAfterTest(true);
205         $this->preventResetByRollback();
207         $this->assertEquals(1, $DB->count_records('course')); // only frontpage in new site
209         // this is weird table - id is NOT a sequence here
210         $this->assertEquals(0, $DB->count_records('context_temp'));
211         $DB->import_record('context_temp', array('id'=>5, 'path'=>'/1/2', 'depth'=>2));
212         $record = $DB->get_record('context_temp', array());
213         $this->assertEquals(5, $record->id);
215         $this->assertEquals(0, $DB->count_records('course_display'));
216         $originaldisplayid = $DB->insert_record('course_display', array('userid'=>2, 'course'=>1, 'display'=>1));
217         $this->assertEquals(1, $originaldisplayid);
219         $course = $this->getDataGenerator()->create_course();
220         $this->assertEquals(2, $course->id);
222         $this->assertEquals(2, $DB->count_records('user'));
223         $DB->delete_records('user', array('id'=>1));
224         $this->assertEquals(1, $DB->count_records('user'));
226         //=========
228         $this->resetAllData();
230         $this->assertEquals(1, $DB->count_records('course')); // only frontpage in new site
231         $this->assertEquals(0, $DB->count_records('context_temp')); // only frontpage in new site
232         $course = $this->getDataGenerator()->create_course();
233         $this->assertEquals(2, $course->id);
235         $displayid = $DB->insert_record('course_display', array('userid'=>2, 'course'=>1, 'display'=>1));
236         $this->assertEquals($originaldisplayid, $displayid);
238         $this->assertEquals(2, $DB->count_records('user'));
239         $DB->delete_records('user', array('id'=>2));
240         $user = $this->getDataGenerator()->create_user();
241         $this->assertEquals(3, $user->id);
243         // =========
245         $this->resetAllData();
247         $course = $this->getDataGenerator()->create_course();
248         $this->assertEquals(2, $course->id);
250         $this->assertEquals(2, $DB->count_records('user'));
251         $DB->delete_records('user', array('id'=>2));
253         //==========
255         $this->resetAllData();
257         $course = $this->getDataGenerator()->create_course();
258         $this->assertEquals(2, $course->id);
260         $this->assertEquals(2, $DB->count_records('user'));
261     }
263     public function test_change_detection() {
264         global $DB, $CFG, $COURSE, $SITE, $USER;
266         $this->preventResetByRollback();
267         phpunit_util::reset_all_data(true);
269         // database change
270         $this->assertEquals(1, $DB->get_field('user', 'confirmed', array('id'=>2)));
271         $DB->set_field('user', 'confirmed', 0, array('id'=>2));
272         try {
273             phpunit_util::reset_all_data(true);
274         } catch (Exception $e) {
275             $this->assertInstanceOf('PHPUnit_Framework_Error_Warning', $e);
276         }
277         $this->assertEquals(1, $DB->get_field('user', 'confirmed', array('id'=>2)));
279         // config change
280         $CFG->xx = 'yy';
281         unset($CFG->admin);
282         $CFG->rolesactive = 0;
283         try {
284             phpunit_util::reset_all_data(true);
285         } catch (Exception $e) {
286             $this->assertInstanceOf('PHPUnit_Framework_Error_Warning', $e);
287             $this->assertContains('xx', $e->getMessage());
288             $this->assertContains('admin', $e->getMessage());
289             $this->assertContains('rolesactive', $e->getMessage());
290         }
291         $this->assertFalse(isset($CFG->xx));
292         $this->assertTrue(isset($CFG->admin));
293         $this->assertEquals(1, $CFG->rolesactive);
295         //silent changes
296         $_SERVER['xx'] = 'yy';
297         phpunit_util::reset_all_data(true);
298         $this->assertFalse(isset($_SERVER['xx']));
300         // COURSE
301         $SITE->id = 10;
302         $COURSE = new stdClass();
303         $COURSE->id = 7;
304         try {
305             phpunit_util::reset_all_data(true);
306         } catch (Exception $e) {
307             $this->assertInstanceOf('PHPUnit_Framework_Error_Warning', $e);
308             $this->assertEquals(1, $SITE->id);
309             $this->assertSame($SITE, $COURSE);
310             $this->assertSame($SITE, $COURSE);
311         }
313         // USER change
314         $this->setUser(2);
315         try {
316             phpunit_util::reset_all_data(true);
317         } catch (Exception $e) {
318             $this->assertInstanceOf('PHPUnit_Framework_Error_Warning', $e);
319             $this->assertEquals(0, $USER->id);
320         }
321     }
323     public function test_getDataGenerator() {
324         $generator = $this->getDataGenerator();
325         $this->assertInstanceOf('phpunit_data_generator', $generator);
326     }
328     public function test_database_mock1() {
329         global $DB;
331         try {
332             $DB->get_record('pokus', array());
333             $this->fail('Exception expected when accessing non existent table');
334         } catch (dml_exception $e) {
335             $this->assertTrue(true);
336         }
337         $DB = $this->getMock(get_class($DB));
338         $this->assertNull($DB->get_record('pokus', array()));
339         // test continues after reset
340     }
342     public function test_database_mock2() {
343         global $DB;
345         // now the database should be back to normal
346         $this->assertFalse($DB->get_record('user', array('id'=>9999)));
347     }
349     public function test_load_dataset() {
350         global $DB;
352         $this->resetAfterTest(true);
354         $this->assertFalse($DB->record_exists('user', array('id'=>5)));
355         $this->assertFalse($DB->record_exists('user', array('id'=>7)));
356         $dataset = $this->createXMLDataSet(__DIR__.'/fixtures/sample_dataset.xml');
357         $this->loadDataSet($dataset);
358         $this->assertTrue($DB->record_exists('user', array('id'=>5)));
359         $this->assertTrue($DB->record_exists('user', array('id'=>7)));
360         $user5 = $DB->get_record('user', array('id'=>5));
361         $user7 = $DB->get_record('user', array('id'=>7));
362         $this->assertEquals('john.doe', $user5->username);
363         $this->assertEquals('jane.doe', $user7->username);
365         $dataset = $this->createCsvDataSet(array('user'=>__DIR__.'/fixtures/sample_dataset.csv'));
366         $this->loadDataSet($dataset);
367         $this->assertEquals(8, $DB->get_field('user', 'id', array('username'=>'pepa.novak')));
368         $this->assertEquals(9, $DB->get_field('user', 'id', array('username'=>'bozka.novakova')));
370         $data = array(
371             'user' => array(
372                 array('username', 'email'),
373                 array('top.secret', 'top@example.com'),
374                 array('low.secret', 'low@example.com'),
375             ),
376         );
377         $dataset = $this->createArrayDataSet($data);
378         $this->loadDataSet($dataset);
379         $this->assertTrue($DB->record_exists('user', array('email'=>'top@example.com')));
380         $this->assertTrue($DB->record_exists('user', array('email'=>'low@example.com')));
382         $data = array(
383             'user' => array(
384                 array('username'=>'noidea', 'email'=>'noidea@example.com'),
385                 array('username'=>'onemore', 'email'=>'onemore@example.com'),
386             ),
387         );
388         $dataset = $this->createArrayDataSet($data);
389         $this->loadDataSet($dataset);
390         $this->assertTrue($DB->record_exists('user', array('username'=>'noidea')));
391         $this->assertTrue($DB->record_exists('user', array('username'=>'onemore')));
392     }
396 /**
397  * Test data generator
398  *
399  * @package    core
400  * @category   phpunit
401  * @copyright  2012 Petr Skoda {@link http://skodak.org}
402  * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
403  */
404 class core_phpunit_generator_testcase extends advanced_testcase {
405     public function test_create() {
406         global $DB;
408         $this->resetAfterTest(true);
409         $generator = $this->getDataGenerator();
411         $count = $DB->count_records('user');
412         $user = $generator->create_user();
413         $this->assertEquals($count+1, $DB->count_records('user'));
415         $count = $DB->count_records('course_categories');
416         $category = $generator->create_category();
417         $this->assertEquals($count+1, $DB->count_records('course_categories'));
419         $count = $DB->count_records('course');
420         $course = $generator->create_course();
421         $this->assertEquals($count+1, $DB->count_records('course'));
423         $section = $generator->create_course_section(array('course'=>$course->id, 'section'=>3));
424         $this->assertEquals($course->id, $section->course);
426         $scale = $generator->create_scale();
427         $this->assertNotEmpty($scale);
428     }
430     public function test_create_module() {
431         global $CFG, $SITE;
432         if (!file_exists("$CFG->dirroot/mod/page/")) {
433             $this->markTestSkipped('Can not find standard Page module');
434         }
436         $this->resetAfterTest(true);
437         $generator = $this->getDataGenerator();
439         $page = $generator->create_module('page', array('course'=>$SITE->id));
440         $this->assertNotEmpty($page);
441     }
443     public function test_create_block() {
444         global $CFG;
445         if (!file_exists("$CFG->dirroot/blocks/online_users/")) {
446             $this->markTestSkipped('Can not find standard Online users block');
447         }
449         $this->resetAfterTest(true);
450         $generator = $this->getDataGenerator();
452         $page = $generator->create_block('online_users');
453         $this->assertNotEmpty($page);
454     }