Proyectos de Subversion Moodle

Rev

Rev 1 | | Comparar con el anterior | Ultima modificación | Ver Log |

Rev Autor Línea Nro. Línea
1 efrain 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
namespace core;
18
 
19
/**
20
 * Test advanced_testcase extra features.
21
 *
22
 * @package    core
23
 * @category   test
24
 * @copyright  2012 Petr Skoda {@link http://skodak.org}
25
 * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
26
 * @coversDefaultClass \advanced_testcase
27
 */
28
class advanced_test extends \advanced_testcase {
29
    public static function setUpBeforeClass(): void {
30
        global $CFG;
31
        require_once(__DIR__ . '/fixtures/adhoc_test_task.php');
32
    }
33
 
11 efrain 34
    public function test_debugging(): void {
1 efrain 35
        global $CFG;
36
        $this->resetAfterTest();
37
 
38
        debugging('hokus');
39
        $this->assertDebuggingCalled();
40
        debugging('pokus');
41
        $this->assertDebuggingCalled('pokus');
42
        debugging('pokus', DEBUG_MINIMAL);
43
        $this->assertDebuggingCalled('pokus', DEBUG_MINIMAL);
44
        $this->assertDebuggingNotCalled();
45
 
46
        debugging('a');
47
        debugging('b', DEBUG_MINIMAL);
48
        debugging('c', DEBUG_DEVELOPER);
49
        $debuggings = $this->getDebuggingMessages();
50
        $this->assertCount(3, $debuggings);
51
        $this->assertSame('a', $debuggings[0]->message);
52
        $this->assertSame(DEBUG_NORMAL, $debuggings[0]->level);
53
        $this->assertSame('b', $debuggings[1]->message);
54
        $this->assertSame(DEBUG_MINIMAL, $debuggings[1]->level);
55
        $this->assertSame('c', $debuggings[2]->message);
56
        $this->assertSame(DEBUG_DEVELOPER, $debuggings[2]->level);
57
 
58
        $this->resetDebugging();
59
        $this->assertDebuggingNotCalled();
60
        $debuggings = $this->getDebuggingMessages();
61
        $this->assertCount(0, $debuggings);
62
 
63
        set_debugging(DEBUG_NONE);
64
        debugging('hokus');
65
        $this->assertDebuggingNotCalled();
66
        set_debugging(DEBUG_DEVELOPER);
67
    }
68
 
69
    /**
70
     * @test
71
     *
72
     * Annotations are a valid PHPUnit method for running tests.  Debugging needs to support them.
73
     */
74
    public function debugging_called_with_annotation() {
75
        debugging('pokus', DEBUG_MINIMAL);
76
        $this->assertDebuggingCalled('pokus', DEBUG_MINIMAL);
77
    }
78
 
11 efrain 79
    public function test_set_user(): void {
1 efrain 80
        global $USER, $DB, $SESSION;
81
 
82
        $this->resetAfterTest();
83
 
84
        $this->assertEquals(0, $USER->id);
85
        $this->assertSame($_SESSION['USER'], $USER);
86
        $this->assertSame($GLOBALS['USER'], $USER);
87
 
88
        $user = $DB->get_record('user', array('id'=>2));
89
        $this->assertNotEmpty($user);
90
        $this->setUser($user);
91
        $this->assertEquals(2, $USER->id);
92
        $this->assertEquals(2, $_SESSION['USER']->id);
93
        $this->assertSame($_SESSION['USER'], $USER);
94
        $this->assertSame($GLOBALS['USER'], $USER);
95
 
96
        $USER->id = 3;
97
        $this->assertEquals(3, $USER->id);
98
        $this->assertEquals(3, $_SESSION['USER']->id);
99
        $this->assertSame($_SESSION['USER'], $USER);
100
        $this->assertSame($GLOBALS['USER'], $USER);
101
 
102
        \core\session\manager::set_user($user);
103
        $this->assertEquals(2, $USER->id);
104
        $this->assertEquals(2, $_SESSION['USER']->id);
105
        $this->assertSame($_SESSION['USER'], $USER);
106
        $this->assertSame($GLOBALS['USER'], $USER);
107
 
108
        $USER = $DB->get_record('user', array('id'=>1));
109
        $this->assertNotEmpty($USER);
110
        $this->assertEquals(1, $USER->id);
111
        $this->assertEquals(1, $_SESSION['USER']->id);
112
        $this->assertSame($_SESSION['USER'], $USER);
113
        $this->assertSame($GLOBALS['USER'], $USER);
114
 
115
        $this->setUser(null);
116
        $this->assertEquals(0, $USER->id);
117
        $this->assertSame($_SESSION['USER'], $USER);
118
        $this->assertSame($GLOBALS['USER'], $USER);
119
 
120
        // Ensure session is reset after setUser, as it may contain extra info.
121
        $SESSION->sometestvalue = true;
122
        $this->setUser($user);
123
        $this->assertObjectNotHasProperty('sometestvalue', $SESSION);
124
    }
125
 
11 efrain 126
    public function test_set_admin_user(): void {
1 efrain 127
        global $USER;
128
 
129
        $this->resetAfterTest();
130
 
131
        $this->setAdminUser();
132
        $this->assertEquals($USER->id, 2);
133
        $this->assertTrue(is_siteadmin());
134
    }
135
 
11 efrain 136
    public function test_set_guest_user(): void {
1 efrain 137
        global $USER;
138
 
139
        $this->resetAfterTest();
140
 
141
        $this->setGuestUser();
142
        $this->assertEquals($USER->id, 1);
143
        $this->assertTrue(isguestuser());
144
    }
145
 
11 efrain 146
    public function test_database_reset(): void {
1 efrain 147
        global $DB;
148
 
149
        $this->resetAfterTest();
150
 
151
        $this->preventResetByRollback();
152
 
153
        $this->assertEquals(1, $DB->count_records('course')); // Only frontpage in new site.
154
 
155
        // This is weird table - id is NOT a sequence here.
156
        $this->assertEquals(0, $DB->count_records('context_temp'));
157
        $DB->import_record('context_temp', array('id'=>5, 'path'=>'/1/2', 'depth'=>2));
158
        $record = $DB->get_record('context_temp', array());
159
        $this->assertEquals(5, $record->id);
160
 
161
        $this->assertEquals(0, $DB->count_records('user_preferences'));
162
        $originaldisplayid = $DB->insert_record('user_preferences', array('userid'=>2, 'name'=> 'phpunittest', 'value'=>'x'));
163
        $this->assertEquals(1, $DB->count_records('user_preferences'));
164
 
165
        $numcourses = $DB->count_records('course');
166
        $course = $this->getDataGenerator()->create_course();
167
        $this->assertEquals($numcourses + 1, $DB->count_records('course'));
168
 
169
        $this->assertEquals(2, $DB->count_records('user'));
170
        $DB->delete_records('user', array('id'=>1));
171
        $this->assertEquals(1, $DB->count_records('user'));
172
 
173
        $this->resetAllData();
174
 
175
        $this->assertEquals(1, $DB->count_records('course')); // Only frontpage in new site.
176
        $this->assertEquals(0, $DB->count_records('context_temp')); // Only frontpage in new site.
177
 
178
        $numcourses = $DB->count_records('course');
179
        $course = $this->getDataGenerator()->create_course();
180
        $this->assertEquals($numcourses + 1, $DB->count_records('course'));
181
 
182
        $displayid = $DB->insert_record('user_preferences', array('userid'=>2, 'name'=> 'phpunittest', 'value'=>'x'));
183
        $this->assertEquals($originaldisplayid, $displayid);
184
 
185
        $this->assertEquals(2, $DB->count_records('user'));
186
        $DB->delete_records('user', array('id'=>2));
187
        $user = $this->getDataGenerator()->create_user();
188
        $this->assertEquals(2, $DB->count_records('user'));
189
        $this->assertGreaterThan(2, $user->id);
190
 
191
        $this->resetAllData();
192
 
193
        $numcourses = $DB->count_records('course');
194
        $course = $this->getDataGenerator()->create_course();
195
        $this->assertEquals($numcourses + 1, $DB->count_records('course'));
196
 
197
        $this->assertEquals(2, $DB->count_records('user'));
198
        $DB->delete_records('user', array('id'=>2));
199
 
200
        $this->resetAllData();
201
 
202
        $numcourses = $DB->count_records('course');
203
        $course = $this->getDataGenerator()->create_course();
204
        $this->assertEquals($numcourses + 1, $DB->count_records('course'));
205
 
206
        $this->assertEquals(2, $DB->count_records('user'));
207
    }
208
 
11 efrain 209
    public function test_change_detection(): void {
1 efrain 210
        global $DB, $CFG, $COURSE, $SITE, $USER;
211
 
212
        $this->preventResetByRollback();
213
        self::resetAllData(true);
214
 
215
        // Database change.
216
        $this->assertEquals(1, $DB->get_field('user', 'confirmed', array('id'=>2)));
217
        $DB->set_field('user', 'confirmed', 0, array('id'=>2));
218
        try {
219
            self::resetAllData(true);
220
        } catch (\Exception $e) {
221
            $this->assertInstanceOf('PHPUnit\Framework\Error\Warning', $e);
222
        }
223
        $this->assertEquals(1, $DB->get_field('user', 'confirmed', array('id'=>2)));
224
 
225
        // Config change.
226
        $CFG->xx = 'yy';
227
        unset($CFG->admin);
228
        $CFG->rolesactive = 0;
229
        try {
230
            self::resetAllData(true);
231
        } catch (\Exception $e) {
232
            $this->assertInstanceOf('PHPUnit\Framework\Error\Warning', $e);
233
            $this->assertStringContainsString('xx', $e->getMessage());
234
            $this->assertStringContainsString('admin', $e->getMessage());
235
            $this->assertStringContainsString('rolesactive', $e->getMessage());
236
        }
237
        $this->assertFalse(isset($CFG->xx));
238
        $this->assertTrue(isset($CFG->admin));
239
        $this->assertEquals(1, $CFG->rolesactive);
240
 
241
        // _GET change.
242
        $_GET['__somethingthatwillnotnormallybepresent__'] = 'yy';
243
        self::resetAllData(true);
244
 
245
        $this->assertEquals(array(), $_GET);
246
 
247
        // _POST change.
248
        $_POST['__somethingthatwillnotnormallybepresent2__'] = 'yy';
249
        self::resetAllData(true);
250
        $this->assertEquals(array(), $_POST);
251
 
252
        // _FILES change.
253
        $_FILES['__somethingthatwillnotnormallybepresent3__'] = 'yy';
254
        self::resetAllData(true);
255
        $this->assertEquals(array(), $_FILES);
256
 
257
        // _REQUEST change.
258
        $_REQUEST['__somethingthatwillnotnormallybepresent4__'] = 'yy';
259
        self::resetAllData(true);
260
        $this->assertEquals(array(), $_REQUEST);
261
 
262
        // Silent changes.
263
        $_SERVER['xx'] = 'yy';
264
        self::resetAllData(true);
265
        $this->assertFalse(isset($_SERVER['xx']));
266
 
267
        // COURSE change.
268
        $SITE->id = 10;
269
        $COURSE = new \stdClass();
270
        $COURSE->id = 7;
271
        try {
272
            self::resetAllData(true);
273
        } catch (\Exception $e) {
274
            $this->assertInstanceOf('PHPUnit\Framework\Error\Warning', $e);
275
            $this->assertEquals(1, $SITE->id);
276
            $this->assertSame($SITE, $COURSE);
277
            $this->assertSame($SITE, $COURSE);
278
        }
279
 
280
        // USER change.
281
        $this->setUser(2);
282
        try {
283
            self::resetAllData(true);
284
        } catch (\Exception $e) {
285
            $this->assertInstanceOf('PHPUnit\Framework\Error\Warning', $e);
286
            $this->assertEquals(0, $USER->id);
287
        }
288
    }
289
 
11 efrain 290
    public function test_getDataGenerator(): void {
1 efrain 291
        $generator = $this->getDataGenerator();
292
        $this->assertInstanceOf('testing_data_generator', $generator);
293
    }
294
 
11 efrain 295
    public function test_database_mock1(): void {
1 efrain 296
        global $DB;
297
 
298
        try {
299
            $DB->get_record('pokus', array());
300
            $this->fail('Exception expected when accessing non existent table');
301
        } catch (\moodle_exception $e) {
302
            $this->assertInstanceOf('dml_exception', $e);
303
        }
304
        $DB = $this->createMock(get_class($DB));
305
        $this->assertNull($DB->get_record('pokus', array()));
306
        // Rest continues after reset.
307
    }
308
 
11 efrain 309
    public function test_database_mock2(): void {
1 efrain 310
        global $DB;
311
 
312
        // Now the database should be back to normal.
313
        $this->assertFalse($DB->get_record('user', array('id'=>9999)));
314
    }
315
 
11 efrain 316
    public function test_assert_time_current(): void {
1 efrain 317
        $this->assertTimeCurrent(time());
318
 
319
        $this->setCurrentTimeStart();
320
        $this->assertTimeCurrent(time());
321
        $this->waitForSecond();
322
        $this->assertTimeCurrent(time());
323
        $this->assertTimeCurrent(time()-1);
324
 
325
        try {
326
            $this->setCurrentTimeStart();
327
            $this->assertTimeCurrent(time()+10);
328
            $this->fail('Failed assert expected');
329
        } catch (\Exception $e) {
330
            $this->assertInstanceOf('PHPUnit\Framework\ExpectationFailedException', $e);
331
        }
332
 
333
        try {
334
            $this->setCurrentTimeStart();
335
            $this->assertTimeCurrent(time()-10);
336
            $this->fail('Failed assert expected');
337
        } catch (\Exception $e) {
338
            $this->assertInstanceOf('PHPUnit\Framework\ExpectationFailedException', $e);
339
        }
340
    }
341
 
342
    /**
343
     * Test the assertEventContextNotUsed() assertion.
344
     *
345
     * Verify that events using the event context in some of their
346
     * methods are detected properly (will throw a warning if they are).
347
     *
348
     * To do so, we'll be using some fixture events (context_used_in_event_xxxx),
349
     * that, on purpose, use the event context (incorrectly) in their methods.
350
     *
351
     * Note that because we are using imported fixture classes, and because we
352
     * are testing for warnings, better we run the tests in a separate process.
353
     *
354
     * @param string $fixture The fixture class to use.
355
     * @param bool $phpwarn Whether a PHP warning is expected.
356
     *
357
     * @runInSeparateProcess
358
     * @dataProvider assert_event_context_not_used_provider
359
     * @covers ::assertEventContextNotUsed
360
     */
361
    public function test_assert_event_context_not_used($fixture, $phpwarn): void {
362
        require(__DIR__ . '/fixtures/event_fixtures.php');
363
        // Create an event that uses the event context in its get_url() and get_description() methods.
364
        $event = $fixture::create([
365
            'other' => [
366
                'sample' => 1,
367
                'xx' => 10,
368
            ],
369
        ]);
370
 
371
        if ($phpwarn) {
372
            // Let's convert the warnings into an assert-able exception.
373
            set_error_handler(
374
                static function ($errno, $errstr) {
375
                    restore_error_handler();
376
                    throw new \Exception($errstr, $errno);
377
                },
378
                E_WARNING // Or any other specific E_ that we want to assert.
379
            );
380
            $this->expectException(\Exception::class);
381
        }
382
        $this->assertEventContextNotUsed($event);
383
    }
384
 
385
    /**
386
     * Data provider for test_assert_event_context_not_used().
387
     *
388
     * @return array
389
     */
390
    public static function assert_event_context_not_used_provider(): array {
391
        return [
392
            'correct' => ['\core\event\context_used_in_event_correct', false],
393
            'wrong_get_url' => ['\core\event\context_used_in_event_get_url', true],
394
            'wrong_get_description' => ['\core\event\context_used_in_event_get_description', true],
395
        ];
396
    }
397
 
11 efrain 398
    public function test_message_processors_reset(): void {
1 efrain 399
        global $DB;
400
 
401
        $this->resetAfterTest(true);
402
 
403
        // Get all processors first.
404
        $processors1 = get_message_processors();
405
 
406
        // Add a new message processor and get all processors again.
407
        $processor = new \stdClass();
408
        $processor->name = 'test_processor';
409
        $processor->enabled = 1;
410
        $DB->insert_record('message_processors', $processor);
411
 
412
        $processors2 = get_message_processors();
413
 
414
        // Assert that new processor still haven't been added to the list.
415
        $this->assertSame($processors1, $processors2);
416
 
417
        // Reset message processors data.
418
        $processors3 = get_message_processors(false, true);
419
        // Now, list of processors should not be the same any more,
420
        // And we should have one more message processor in the list.
421
        $this->assertNotSame($processors1, $processors3);
422
        $this->assertEquals(count($processors1) + 1, count($processors3));
423
    }
424
 
11 efrain 425
    public function test_message_redirection(): \phpunit_message_sink {
1 efrain 426
        $this->preventResetByRollback(); // Messaging is not compatible with transactions...
427
        $this->resetAfterTest(false);
428
 
429
        $user1 = $this->getDataGenerator()->create_user();
430
        $user2 = $this->getDataGenerator()->create_user();
431
 
432
        // Any core message will do here.
433
        $message1 = new \core\message\message();
434
        $message1->courseid          = 1;
435
        $message1->component         = 'moodle';
436
        $message1->name              = 'instantmessage';
437
        $message1->userfrom          = $user1;
438
        $message1->userto            = $user2;
439
        $message1->subject           = 'message subject 1';
440
        $message1->fullmessage       = 'message body';
441
        $message1->fullmessageformat = FORMAT_MARKDOWN;
442
        $message1->fullmessagehtml   = '<p>message body</p>';
443
        $message1->smallmessage      = 'small message';
444
        $message1->notification      = 0;
445
 
446
        $message2 = new \core\message\message();
447
        $message2->courseid          = 1;
448
        $message2->component         = 'moodle';
449
        $message2->name              = 'instantmessage';
450
        $message2->userfrom          = $user2;
451
        $message2->userto            = $user1;
452
        $message2->subject           = 'message subject 2';
453
        $message2->fullmessage       = 'message body';
454
        $message2->fullmessageformat = FORMAT_MARKDOWN;
455
        $message2->fullmessagehtml   = '<p>message body</p>';
456
        $message2->smallmessage      = 'small message';
457
        $message2->notification      = 0;
458
 
459
        // There should be debugging message without redirection.
460
        $mailsink = $this->redirectEmails();
461
        $mailsink->close();
462
        message_send($message1);
463
        $this->assertDebuggingCalled(null, null, 'message_send() must print debug message that messaging is disabled in phpunit tests.');
464
 
465
        // Sink should catch messages.
466
        $sink = $this->redirectMessages();
467
        $mid1 = message_send($message1);
468
        $mid2 = message_send($message2);
469
 
470
        $this->assertDebuggingNotCalled('message redirection must prevent debug messages from the message_send()');
471
        $this->assertEquals(2, $sink->count());
472
        $this->assertGreaterThanOrEqual(1, $mid1);
473
        $this->assertGreaterThanOrEqual($mid1, $mid2);
474
 
475
        $messages = $sink->get_messages();
476
        $this->assertIsArray($messages);
477
        $this->assertCount(2, $messages);
478
        $this->assertEquals($mid1, $messages[0]->id);
479
        $this->assertEquals($message1->userto->id, $messages[0]->useridto);
480
        $this->assertEquals($message1->userfrom->id, $messages[0]->useridfrom);
481
        $this->assertEquals($message1->smallmessage, $messages[0]->smallmessage);
482
        $this->assertEquals($mid2, $messages[1]->id);
483
        $this->assertEquals($message2->userto->id, $messages[1]->useridto);
484
        $this->assertEquals($message2->userfrom->id, $messages[1]->useridfrom);
485
        $this->assertEquals($message2->smallmessage, $messages[1]->smallmessage);
486
 
487
        // Test resetting.
488
        $sink->clear();
489
        $messages = $sink->get_messages();
490
        $this->assertIsArray($messages);
491
        $this->assertCount(0, $messages);
492
 
493
        message_send($message1);
494
        $messages = $sink->get_messages();
495
        $this->assertIsArray($messages);
496
        $this->assertCount(1, $messages);
497
 
498
        // Test closing.
499
        $sink->close();
500
        $messages = $sink->get_messages();
501
        $this->assertIsArray($messages);
502
        $this->assertCount(1, $messages, 'Messages in sink are supposed to stay there after close');
503
 
504
        // Test debugging is enabled again.
505
        message_send($message1);
506
        $this->assertDebuggingCalled(null, null, 'message_send() must print debug message that messaging is disabled in phpunit tests.');
507
 
508
        // Test invalid names and components.
509
 
510
        $sink = $this->redirectMessages();
511
 
512
        $message3 = new \core\message\message();
513
        $message3->courseid          = 1;
514
        $message3->component         = 'xxxx_yyyyy';
515
        $message3->name              = 'instantmessage';
516
        $message3->userfrom          = $user2;
517
        $message3->userto            = $user1;
518
        $message3->subject           = 'message subject 2';
519
        $message3->fullmessage       = 'message body';
520
        $message3->fullmessageformat = FORMAT_MARKDOWN;
521
        $message3->fullmessagehtml   = '<p>message body</p>';
522
        $message3->smallmessage      = 'small message';
523
        $message3->notification      = 0;
524
 
525
        $this->assertFalse(message_send($message3));
526
        $this->assertDebuggingCalled('Attempt to send msg from a provider xxxx_yyyyy/instantmessage '.
527
            'that is inactive or not allowed for the user id='.$user1->id);
528
 
529
        $message3->component = 'moodle';
530
        $message3->name      = 'yyyyyy';
531
 
532
        $this->assertFalse(message_send($message3));
533
        $this->assertDebuggingCalled('Attempt to send msg from a provider moodle/yyyyyy '.
534
            'that is inactive or not allowed for the user id='.$user1->id);
535
 
536
        message_send($message1);
537
        $this->assertEquals(1, $sink->count());
538
 
539
        // Test if sink can be carried over to next test.
540
        $this->assertTrue(\phpunit_util::is_redirecting_messages());
541
        return $sink;
542
    }
543
 
544
    /**
545
     * @depends test_message_redirection
546
     */
11 efrain 547
    public function test_message_redirection_noreset(\phpunit_message_sink $sink): void {
1 efrain 548
        if ($this->isInIsolation()) {
549
            $this->markTestSkipped('State cannot be carried over between tests in isolated tests');
550
        }
551
 
552
        $this->preventResetByRollback(); // Messaging is not compatible with transactions...
553
        $this->resetAfterTest();
554
 
555
        $this->assertTrue(\phpunit_util::is_redirecting_messages());
556
        $this->assertEquals(1, $sink->count());
557
 
558
        $message = new \core\message\message();
559
        $message->courseid          = 1;
560
        $message->component         = 'moodle';
561
        $message->name              = 'instantmessage';
562
        $message->userfrom          = get_admin();
563
        $message->userto            = get_admin();
564
        $message->subject           = 'message subject 1';
565
        $message->fullmessage       = 'message body';
566
        $message->fullmessageformat = FORMAT_MARKDOWN;
567
        $message->fullmessagehtml   = '<p>message body</p>';
568
        $message->smallmessage      = 'small message';
569
        $message->notification      = 0;
570
 
571
        message_send($message);
572
        $this->assertEquals(2, $sink->count());
573
    }
574
 
575
    /**
576
     * @depends test_message_redirection_noreset
577
     */
11 efrain 578
    public function test_message_redirection_reset(): void {
1 efrain 579
        $this->assertFalse(\phpunit_util::is_redirecting_messages(), 'Test reset must stop message redirection.');
580
    }
581
 
11 efrain 582
    public function test_set_timezone(): void {
1 efrain 583
        global $CFG;
584
        $this->resetAfterTest();
585
 
586
        $this->assertSame('Australia/Perth', $CFG->timezone);
587
        $this->assertSame('Australia/Perth', date_default_timezone_get());
588
 
589
        $this->setTimezone('Pacific/Auckland', 'Europe/Prague');
590
        $this->assertSame('Pacific/Auckland', $CFG->timezone);
591
        $this->assertSame('Pacific/Auckland', date_default_timezone_get());
592
 
593
        $this->setTimezone('99', 'Europe/Prague');
594
        $this->assertSame('99', $CFG->timezone);
595
        $this->assertSame('Europe/Prague', date_default_timezone_get());
596
 
597
        $this->setTimezone('xxx', 'Europe/Prague');
598
        $this->assertSame('xxx', $CFG->timezone);
599
        $this->assertSame('Europe/Prague', date_default_timezone_get());
600
 
601
        $this->setTimezone();
602
        $this->assertSame('Australia/Perth', $CFG->timezone);
603
        $this->assertSame('Australia/Perth', date_default_timezone_get());
604
 
605
        try {
606
            $this->setTimezone('Pacific/Auckland', '');
607
        } catch (\Exception $e) {
608
            $this->assertInstanceOf('PHPUnit\Framework\Error\Warning', $e);
609
        }
610
 
611
        try {
612
            $this->setTimezone('Pacific/Auckland', 'xxxx');
613
        } catch (\Exception $e) {
614
            $this->assertInstanceOf('PHPUnit\Framework\Error\Warning', $e);
615
        }
616
 
617
        try {
618
            $this->setTimezone('Pacific/Auckland', null);
619
        } catch (\Exception $e) {
620
            $this->assertInstanceOf('PHPUnit\Framework\Error\Warning', $e);
621
        }
622
 
623
    }
624
 
11 efrain 625
    public function test_locale_reset(): void {
1 efrain 626
        global $CFG;
627
 
628
        $this->resetAfterTest();
629
 
630
        // If this fails self::resetAllData(); must be updated.
631
        $this->assertSame('en_AU.UTF-8', get_string('locale', 'langconfig'));
632
        $this->assertSame('English_Australia.1252', get_string('localewin', 'langconfig'));
633
 
634
        if ($CFG->ostype === 'WINDOWS') {
635
            $this->assertSame('English_Australia.1252', setlocale(LC_TIME, 0));
636
            setlocale(LC_TIME, 'English_USA.1252');
637
        } else {
638
            $this->assertSame('en_AU.UTF-8', setlocale(LC_TIME, 0));
639
            setlocale(LC_TIME, 'en_US.UTF-8');
640
        }
641
 
642
        try {
643
            self::resetAllData(true);
644
        } catch (\Exception $e) {
645
            $this->assertInstanceOf('PHPUnit\Framework\Error\Warning', $e);
646
        }
647
 
648
        if ($CFG->ostype === 'WINDOWS') {
649
            $this->assertSame('English_Australia.1252', setlocale(LC_TIME, 0));
650
        } else {
651
            $this->assertSame('en_AU.UTF-8', setlocale(LC_TIME, 0));
652
        }
653
 
654
        if ($CFG->ostype === 'WINDOWS') {
655
            $this->assertSame('English_Australia.1252', setlocale(LC_TIME, 0));
656
            setlocale(LC_TIME, 'English_USA.1252');
657
        } else {
658
            $this->assertSame('en_AU.UTF-8', setlocale(LC_TIME, 0));
659
            setlocale(LC_TIME, 'en_US.UTF-8');
660
        }
661
 
662
        self::resetAllData(false);
663
 
664
        if ($CFG->ostype === 'WINDOWS') {
665
            $this->assertSame('English_Australia.1252', setlocale(LC_TIME, 0));
666
        } else {
667
            $this->assertSame('en_AU.UTF-8', setlocale(LC_TIME, 0));
668
        }
669
    }
670
 
671
    /**
672
     * This test sets a user agent and makes sure that it is cleared when the test is reset.
673
     */
11 efrain 674
    public function test_it_resets_useragent_after_test(): void {
1 efrain 675
        $this->resetAfterTest();
676
        $fakeagent = 'New user agent set.';
677
 
678
        // Sanity check: it should not be set when test begins.
679
        self::assertFalse(\core_useragent::get_user_agent_string(), 'It should not be set at first.');
680
 
681
        // Set a fake useragent and check it was set properly.
682
        \core_useragent::instance(true, $fakeagent);
683
        self::assertSame($fakeagent, \core_useragent::get_user_agent_string(), 'It should be the forced agent.');
684
 
685
        // Reset test data and ansure the useragent was cleaned.
686
        self::resetAllData(false);
687
        self::assertFalse(\core_useragent::get_user_agent_string(), 'It should not be set again, data was reset.');
688
    }
689
 
690
    /**
691
     * @covers ::runAdhocTasks
692
     */
693
    public function test_runadhoctasks_no_tasks_queued(): void {
694
        $this->runAdhocTasks();
695
        $this->expectOutputRegex('/^$/');
696
    }
697
 
698
    /**
699
     * @covers ::runAdhocTasks
700
     */
701
    public function test_runadhoctasks_tasks_queued(): void {
702
        $this->resetAfterTest(true);
703
        $admin = get_admin();
704
        \core\task\manager::queue_adhoc_task(new \core_phpunit\adhoc_test_task());
705
        $this->runAdhocTasks();
706
        $this->expectOutputRegex("/Task was run as {$admin->id}/");
707
    }
708
 
709
    /**
710
     * @covers ::runAdhocTasks
711
     */
712
    public function test_runadhoctasks_with_existing_user_change(): void {
713
        $this->resetAfterTest(true);
714
        $admin = get_admin();
715
 
716
        $this->setGuestUser();
717
        \core\task\manager::queue_adhoc_task(new \core_phpunit\adhoc_test_task());
718
        $this->runAdhocTasks();
719
        $this->expectOutputRegex("/Task was run as {$admin->id}/");
720
    }
721
 
722
    /**
723
     * @covers ::runAdhocTasks
724
     */
725
    public function test_runadhoctasks_with_existing_user_change_and_specified(): void {
726
        global $USER;
727
 
728
        $this->resetAfterTest(true);
729
        $user = $this->getDataGenerator()->create_user();
730
 
731
        $this->setGuestUser();
732
        $task = new \core_phpunit\adhoc_test_task();
733
        $task->set_userid($user->id);
734
        \core\task\manager::queue_adhoc_task($task);
735
        $this->runAdhocTasks();
736
        $this->expectOutputRegex("/Task was run as {$user->id}/");
737
    }
738
 
739
    /**
740
     * Test the incrementing mock clock.
741
     *
742
     * @covers ::mock_clock_with_incrementing
743
     * @covers \incrementing_clock
744
     */
745
    public function test_mock_clock_with_incrementing(): void {
746
        $standard = \core\di::get(\core\clock::class);
747
        $this->assertInstanceOf(\Psr\Clock\ClockInterface::class, $standard);
748
        $this->assertInstanceOf(\core\clock::class, $standard);
749
 
750
        $newclock = $this->mock_clock_with_incrementing(0);
751
        $mockedclock = \core\di::get(\core\clock::class);
752
        $this->assertInstanceOf(\incrementing_clock::class, $newclock);
753
        $this->assertSame($newclock, $mockedclock);
754
 
755
        // Test the functionality.
756
        $this->assertEquals(0, $mockedclock->now()->getTimestamp());
757
        $this->assertEquals(1, $newclock->now()->getTimestamp());
758
        $this->assertEquals(2, $mockedclock->now()->getTimestamp());
759
 
760
        // Specify a specific start time.
761
        $newclock = $this->mock_clock_with_incrementing(12345);
762
        $mockedclock = \core\di::get(\core\clock::class);
763
        $this->assertSame($newclock, $mockedclock);
764
 
765
        $this->assertEquals(12345, $mockedclock->now()->getTimestamp());
766
        $this->assertEquals(12346, $newclock->now()->getTimestamp());
767
        $this->assertEquals(12347, $mockedclock->now()->getTimestamp());
768
 
769
        $this->assertEquals($newclock->time, $mockedclock->now()->getTimestamp());
770
    }
771
 
772
    /**
773
     * Test the incrementing mock clock.
774
     *
775
     * @covers ::mock_clock_with_frozen
776
     * @covers \frozen_clock
777
     */
778
    public function test_mock_clock_with_frozen(): void {
779
        $standard = \core\di::get(\core\clock::class);
780
        $this->assertInstanceOf(\Psr\Clock\ClockInterface::class, $standard);
781
        $this->assertInstanceOf(\core\clock::class, $standard);
782
 
783
        $newclock = $this->mock_clock_with_frozen(0);
784
        $mockedclock = \core\di::get(\core\clock::class);
785
        $this->assertInstanceOf(\frozen_clock::class, $newclock);
786
        $this->assertSame($newclock, $mockedclock);
787
 
788
        // Test the functionality.
789
        $initialtime = $mockedclock->now()->getTimestamp();
790
        $this->assertEquals($initialtime, $newclock->now()->getTimestamp());
791
        $this->assertEquals($initialtime, $mockedclock->now()->getTimestamp());
792
 
793
        // Specify a specific start time.
794
        $newclock = $this->mock_clock_with_frozen(12345);
795
        $mockedclock = \core\di::get(\core\clock::class);
796
        $this->assertSame($newclock, $mockedclock);
797
 
798
        $initialtime = $mockedclock->now();
799
        $this->assertEquals($initialtime, $mockedclock->now());
800
        $this->assertEquals($initialtime, $newclock->now());
801
        $this->assertEquals($initialtime, $mockedclock->now());
802
    }
803
}