Proyectos de Subversion Moodle

Rev

Rev 11 | | 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
defined('MOODLE_INTERNAL') || die();
20
 
21
global $CFG;
22
require_once($CFG->libdir . '/adminlib.php');
23
require_once($CFG->libdir . '/statslib.php');
24
require_once(__DIR__ . '/fixtures/stats_events.php');
25
 
26
/**
27
 * Test functions that affect daily stats.
28
 *
29
 * @package    core
30
 * @category   test
31
 * @copyright  2012 Tyler Bannister
32
 * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
33
 */
1441 ariadna 34
final class statslib_test extends \advanced_testcase {
1 efrain 35
    /** The day to use for testing **/
36
    const DAY = 1272672000;
37
 
38
    /** The timezone to use for testing **/
39
    const TIMEZONE = 0;
40
 
41
    /** @var array The list of temporary tables created for the statistic calculations **/
42
    protected $tables = array('temp_log1', 'temp_log2', 'temp_stats_daily', 'temp_stats_user_daily');
43
 
44
    /** @var array The replacements to be used when loading XML files **/
45
    protected $replacements = null;
46
 
47
 
48
    /**
49
     * Setup function
50
     *   - Allow changes to CFG->debug for testing purposes.
51
     */
52
    protected function setUp(): void {
53
        global $CFG, $DB;
54
        parent::setUp();
55
 
56
        // Settings to force statistic to run during testing.
57
        $this->setTimezone(self::TIMEZONE);
58
        \core_date::set_default_server_timezone();
59
        $CFG->statsfirstrun           = 'all';
60
        $CFG->statslastdaily          = 0;
61
 
62
        // Figure out the broken day start so I can figure out when to the start time should be.
63
        $time   = time();
64
        // This nonsense needs to be rewritten.
65
        $date = new \DateTime('now', \core_date::get_server_timezone_object());
66
        $offset = $date->getOffset();
67
        $stime  = $time + $offset;
68
        $stime  = intval($stime / (60*60*24)) * 60*60*24;
69
        $stime -= $offset;
70
 
71
        $shour  = intval(($time - $stime) / (60*60));
72
 
73
        if ($DB->record_exists('user', array('username' => 'user1'))) {
74
            return;
75
        }
76
 
77
        // Set up the database.
78
        $datagen = self::getDataGenerator();
79
 
80
        $user1   = $datagen->create_user(array('username'=>'user1'));
81
        $user2   = $datagen->create_user(array('username'=>'user2'));
82
 
83
        $course1 = $datagen->create_course(array('shortname'=>'course1'));
84
        $datagen->enrol_user($user1->id, $course1->id);
85
 
86
        $this->generate_replacement_list();
87
 
88
        // Reset between tests.
89
        $this->resetAfterTest();
90
    }
91
 
92
    /**
93
     * Function to setup database.
94
     *
95
     * @param phpunit_dataset $dataset Containing all the information loaded from fixtures.
96
     * @param array $filter Tables to be sent to database.
97
     */
98
    protected function prepare_db($dataset, $tables) {
99
        global $DB;
100
 
101
        foreach ($tables as $tablename) {
102
            $DB->delete_records($tablename);
103
            $dataset->to_database([$tablename]);
104
        }
105
    }
106
 
107
    /**
108
     * Load dataset from XML file.
109
     */
110
    protected function generate_replacement_list() {
111
        global $CFG, $DB;
112
 
113
        if ($this->replacements !== null) {
114
            return;
115
        }
116
 
117
        $this->setTimezone(self::TIMEZONE);
118
 
119
        $guest = $DB->get_record('user', array('id' => $CFG->siteguest));
120
        $user1 = $DB->get_record('user', array('username' => 'user1'));
121
        $user2 = $DB->get_record('user', array('username' => 'user2'));
122
 
123
        if (($guest === false) || ($user1 === false) || ($user2 === false)) {
124
            trigger_error('User setup incomplete', E_USER_ERROR);
125
        }
126
 
127
        $site    = $DB->get_record('course', array('id' => SITEID));
128
        $course1 = $DB->get_record('course', array('shortname' => 'course1'));
129
 
130
        if (($site === false) || ($course1 === false)) {
131
            trigger_error('Course setup incomplete', E_USER_ERROR);
132
        }
133
 
134
        $start      = stats_get_base_daily(self::DAY + 3600);
135
        $startnolog = stats_get_base_daily(stats_get_start_from('daily'));
136
        $gr         = get_guest_role();
137
        $studentrole = $DB->get_record('role', array('shortname' => 'student'));
138
 
139
        $this->replacements = array(
140
            // Start and end times.
141
            '[start_0]'          => $start -  14410,  // 4 hours before.
142
            '[start_1]'          => $start +  14410,  // 4 hours after.
143
            '[start_2]'          => $start +  14420,
144
            '[start_3]'          => $start +  14430,
145
            '[start_4]'          => $start + 100800, // 28 hours after.
146
            '[end]'              => stats_get_next_day_start($start),
147
            '[end_no_logs]'      => stats_get_next_day_start($startnolog),
148
 
149
            // User ids.
150
            '[guest_id]'         => $guest->id,
151
            '[user1_id]'         => $user1->id,
152
            '[user2_id]'         => $user2->id,
153
 
154
            // Course ids.
155
            '[course1_id]'       => $course1->id,
156
            '[site_id]'          => SITEID,
157
 
158
            // Role ids.
159
            '[frontpage_roleid]' => (int) $CFG->defaultfrontpageroleid,
160
            '[guest_roleid]'     => $gr->id,
161
            '[student_roleid]'   => $studentrole->id,
162
        );
163
    }
164
 
165
    /**
166
     * Load dataset from XML file.
167
     *
168
     * @param string $file The name of the file to load
169
     * @return phpunit_dataset
170
     */
171
    protected function load_xml_data_file($file) {
172
 
173
        $xml = file_get_contents($file);
174
 
175
        // Apply all the replacements straight in xml.
176
        foreach ($this->replacements as $placeholder => $value) {
177
            $placeholder = preg_quote($placeholder, '/');
178
            $xml = preg_replace('/' . $placeholder . '/', $value, $xml);
179
        }
180
 
181
        return $this->dataset_from_string($xml, 'xml');
182
    }
183
 
184
    /**
185
     * Provides the log data for test_statslib_cron_daily.
186
     *
187
     * @return array of fixture XML log file names.
188
     */
1441 ariadna 189
    public static function daily_log_provider(): array {
1 efrain 190
        $logfiles = array();
191
        $fileno = array('00', '01', '02', '03', '04', '05', '06', '07', '08');
192
 
193
        foreach ($fileno as $no) {
194
            $logfiles[] = array("statslib-test{$no}.xml");
195
        }
196
 
197
        return $logfiles;
198
    }
199
 
200
    /**
201
     * Set of data for test_statlibs_get_base_weekly
202
     *
203
     * @return array Dates and timezones for which the first day of the week will be calculated
204
     */
1441 ariadna 205
    public static function get_base_weekly_provider(): array {
1 efrain 206
        return [
207
            [
208
                "startwday" => 0,
209
                "timezone" => 'America/Chicago',
210
                "timestart" => '18-03-2017 22:00',
211
                "expected" => '12-03-2017 00:00:00'
212
            ],
213
            [
214
                "startwday" => 0,
215
                "timezone" => 'America/Chicago',
1441 ariadna 216
                "timestart" => '25-03-2017 22:00',
1 efrain 217
                "expected" => '19-03-2017 00:00:00'
218
            ],
219
            [
220
                "startwday" => 1,
221
                "timezone" => 'Atlantic/Canary',
1441 ariadna 222
                "timestart" => '06-08-2018 22:00',
1 efrain 223
                "expected" => '06-08-2018 00:00:00'
224
            ],
225
        ];
226
    }
227
 
228
    /**
229
     * Compare the expected stats to those in the database.
230
     *
231
     * @param array $expected
232
     * @param string $output
233
     */
234
    protected function verify_stats($expected, $output = '') {
235
        global $DB;
236
 
237
        // Note: We can not use $this->assertDataSetEqual($expected, $actual) because there's no
238
        //       $this->getConnection() in advanced_testcase.
239
 
240
        foreach ($expected as $type => $table) {
241
            $records = $DB->get_records($type);
242
 
243
            $rows = count($table);
244
 
245
            $message = 'Incorrect number of results returned for '. $type;
246
 
247
            if ($output != '') {
248
                $message .= "\nCron output:\n$output";
249
            }
250
 
251
            $this->assertCount($rows, $records, $message);
252
 
253
            for ($i = 0; $i < $rows; $i++) {
254
                $row   = $table[$i];
255
                $found = 0;
256
 
257
                foreach ($records as $key => $record) {
258
                    $record = (array) $record;
259
                    unset($record['id']);
260
                    $diff = array_merge(array_diff_assoc($row, $record),
261
                            array_diff_assoc($record, $row));
262
 
263
                    if (empty($diff)) {
264
                        $found = $key;
265
                        break;
266
                    }
267
                }
268
 
269
                $this->assertGreaterThan(0, $found, 'Expected log '. var_export($row, true)
270
                                        ." was not found in $type ". var_export($records, true));
271
                unset($records[$found]);
272
            }
273
        }
274
    }
275
 
276
    /**
277
     * Test progress output when debug is on.
278
     */
11 efrain 279
    public function test_statslib_progress_debug(): void {
1 efrain 280
        set_debugging(DEBUG_ALL);
281
        $this->expectOutputString('1:0 ');
282
        stats_progress('init');
283
        stats_progress('1');
284
        $this->resetDebugging();
285
    }
286
 
287
    /**
288
     * Test progress output when debug is off.
289
     */
11 efrain 290
    public function test_statslib_progress_no_debug(): void {
1 efrain 291
        set_debugging(DEBUG_NONE);
292
        $this->expectOutputString('.');
293
        stats_progress('init');
294
        stats_progress('1');
295
        $this->resetDebugging();
296
    }
297
 
298
    /**
299
     * Test the function that gets the start date from the config.
300
     */
11 efrain 301
    public function test_statslib_get_start_from(): void {
1 efrain 302
        global $CFG, $DB;
303
 
304
        $dataset = $this->load_xml_data_file(__DIR__."/fixtures/statslib-test01.xml");
305
        $DB->delete_records('log');
306
 
307
        $date = new \DateTime('now', \core_date::get_server_timezone_object());
308
        $day = self::DAY - $date->getOffset();
309
 
310
        $CFG->statsfirstrun = 'all';
311
        // Allow 1 second difference in case we cross a second boundary.
312
        // Note: within 3 days of a DST change - -3 days != 3 * 24 hours (it may be more or less).
313
        $this->assertLessThanOrEqual(1, stats_get_start_from('daily') - strtotime('-3 days', time()), 'All start time');
314
 
315
        $this->prepare_db($dataset, array('log'));
316
        $records = $DB->get_records('log');
317
 
318
        $this->assertEquals($day + 14410, stats_get_start_from('daily'), 'Log entry start');
319
 
320
        $CFG->statsfirstrun = 'none';
321
        $this->assertLessThanOrEqual(1, stats_get_start_from('daily') - strtotime('-3 days', time()), 'None start time');
322
 
323
        $CFG->statsfirstrun = 14515200;
324
        $this->assertLessThanOrEqual(1, stats_get_start_from('daily') - (time() - (14515200)), 'Specified start time');
325
 
326
        $this->prepare_db($dataset, array('stats_daily'));
327
        $this->assertEquals($day + DAYSECS, stats_get_start_from('daily'), 'Daily stats start time');
328
 
329
        // New log stores.
330
        $this->preventResetByRollback();
331
 
332
        $this->assertFileExists("$CFG->dirroot/$CFG->admin/tool/log/store/standard/version.php");
333
        set_config('enabled_stores', 'logstore_standard', 'tool_log');
334
        set_config('buffersize', 0, 'logstore_standard');
335
        set_config('logguests', 1, 'logstore_standard');
336
        get_log_manager(true);
337
 
338
        $this->assertEquals(0, $DB->count_records('logstore_standard_log'));
339
 
340
        $DB->delete_records('stats_daily');
341
        $CFG->statsfirstrun = 'all';
342
        $firstoldtime = $DB->get_field_sql('SELECT MIN(time) FROM {log}');
343
 
344
        $this->assertEquals($firstoldtime, stats_get_start_from('daily'));
345
 
346
        $time = time() - 5;
347
        \core_tests\event\create_executed::create(array('context' => \context_system::instance()))->trigger();
348
        $DB->set_field('logstore_standard_log', 'timecreated', $time++, [
349
                'eventname' => '\\core_tests\\event\\create_executed',
350
            ]);
351
 
352
        \core_tests\event\read_executed::create(array('context' => \context_system::instance()))->trigger();
353
        $DB->set_field('logstore_standard_log', 'timecreated', $time++, [
354
                'eventname' => '\\core_tests\\event\\read_executed',
355
            ]);
356
 
357
        \core_tests\event\update_executed::create(array('context' => \context_system::instance()))->trigger();
358
        $DB->set_field('logstore_standard_log', 'timecreated', $time++, [
359
                'eventname' => '\\core_tests\\event\\update_executed',
360
            ]);
361
 
362
        \core_tests\event\delete_executed::create(array('context' => \context_system::instance()))->trigger();
363
        $DB->set_field('logstore_standard_log', 'timecreated', $time++, [
364
                'eventname' => '\\core_tests\\event\\delete_executed',
365
            ]);
366
 
367
        $DB->set_field('logstore_standard_log', 'origin', 'web', array());
368
        $logs = $DB->get_records('logstore_standard_log', null, 'timecreated ASC');
369
        $this->assertCount(4, $logs);
370
 
371
        $firstnew = reset($logs);
372
        $this->assertGreaterThan($firstoldtime, $firstnew->timecreated);
373
        $DB->set_field('logstore_standard_log', 'timecreated', 10, array('id' => $firstnew->id));
374
        $this->assertEquals(10, stats_get_start_from('daily'));
375
 
376
        $DB->set_field('logstore_standard_log', 'timecreated', $firstnew->timecreated, array('id' => $firstnew->id));
377
        $DB->delete_records('log');
378
        $this->assertEquals($firstnew->timecreated, stats_get_start_from('daily'));
379
 
380
        set_config('enabled_stores', '', 'tool_log');
381
        get_log_manager(true);
382
    }
383
 
384
    /**
385
     * Test the function that calculates the start of the day.
386
     *
387
     * NOTE: I don't think this is the way this function should work.
388
     *       This test documents the current functionality.
389
     */
11 efrain 390
    public function test_statslib_get_base_daily(): void {
1 efrain 391
        global $CFG;
392
 
393
        for ($x = 0; $x < 13; $x += 1) {
394
            $this->setTimezone($x);
395
 
396
            $start = 1272672000 - ($x * 3600);
397
            if ($x >= 20) {
398
                $start += (24 * 3600);
399
            }
400
 
401
            $this->assertEquals($start, stats_get_base_daily(1272686410), "Timezone $x check");
402
        }
403
    }
404
 
405
    /**
406
     * Test the function that gets the start of the next day.
407
     */
11 efrain 408
    public function test_statslib_get_next_day_start(): void {
1 efrain 409
        $this->setTimezone(0);
410
        $this->assertEquals(1272758400, stats_get_next_day_start(1272686410));
411
 
412
        // Try setting timezone to some place in the US.
413
        $this->setTimezone('America/New_York', 'America/New_York');
414
        // Then set the time for midnight before daylight savings.
415
        // 1425790800 is midnight in New York (2015-03-08) Daylight saving will occur in 2 hours time.
416
        // 1425873600 is midnight the next day.
417
        $this->assertEquals(1425873600, stats_get_next_day_start(1425790800));
418
        $this->assertEquals(23, ((1425873600 - 1425790800) / 60 ) / 60);
419
        // Then set the time for midnight before daylight savings ends.
420
        // 1446350400 is midnight in New York (2015-11-01) Daylight saving will finish in 2 hours time.
421
        // 1446440400 is midnight the next day.
422
        $this->assertEquals(1446440400, stats_get_next_day_start(1446350400));
423
        $this->assertEquals(25, ((1446440400 - 1446350400) / 60 ) / 60);
424
        // The next day should be normal.
425
        $this->assertEquals(1446526800, stats_get_next_day_start(1446440400));
426
        $this->assertEquals(24, ((1446526800 - 1446440400) / 60 ) / 60);
427
    }
428
 
429
    /**
430
     * Test the function that calculates the start of the week.
431
     *
432
     * @dataProvider get_base_weekly_provider
433
     * @param int $startwday Day in which the week starts (Sunday = 0)
434
     * @param string $timezone Default timezone
435
     * @param string $timestart Date and time for which the first day of the week will be obtained
436
     * @param string $expected Expected date of the first day of the week
437
     */
11 efrain 438
    public function test_statslib_get_base_weekly($startwday, $timezone, $timestart, $expected): void {
1 efrain 439
        $this->setTimezone($timezone);
440
        $time = strtotime($timestart);
441
        $expected = strtotime($expected);
442
        set_config('calendar_startwday', $startwday);
443
        set_config('statslastweekly', $time);
444
 
445
        $weekstarttime = stats_get_base_weekly($time);
446
 
447
        $this->assertEquals($expected, $weekstarttime);
448
    }
449
 
450
    /**
451
     * Test the function that gets the action names.
452
     *
453
     * Note: The function results depend on installed modules.  The hard coded lists are the
454
     *       defaults for a new Moodle 2.3 install.
455
     */
11 efrain 456
    public function test_statslib_get_action_names(): void {
1441 ariadna 457
        $basepostactions = [
458
            'add',
459
            'delete',
460
            'edit',
461
            'add mod',
462
            'delete mod',
463
            'edit section',
464
            'loginas',
465
            'new',
466
            'unenrol',
467
            'update',
468
            'update mod',
469
            'upload',
470
            'submit',
471
            'submit for grading',
472
            'choose',
473
            'choose again',
474
            'record delete',
475
            'add discussion',
476
            'add post',
477
            'delete discussion',
478
            'delete post',
479
            'move discussion',
480
            'prune post',
481
            'update post',
482
            'add category',
483
            'add entry',
484
            'approve entry',
485
            'delete category',
486
            'delete entry',
487
            'edit category',
488
            'update entry',
489
            'end',
490
            'start',
491
            'attempt',
492
            'close attempt',
493
            'preview',
494
            'editquestions',
495
            'delete attempt',
496
            'manualgrade',
497
            'enrol',
498
        ];
1 efrain 499
 
1441 ariadna 500
        $baseviewactions = [
501
            'view',
502
            'view all',
503
            'history',
504
            'view submission',
505
            'view feedback',
506
            'print',
507
            'report',
508
            'view discussion',
509
            'search',
510
            'forum',
511
            'forums',
512
            'subscribers',
513
            'view forum',
514
            'view entry',
515
            'review',
516
            'pre-view',
517
        ];
1 efrain 518
 
519
        $postactions = stats_get_action_names('post');
520
 
521
        foreach ($basepostactions as $action) {
522
            $this->assertContains($action, $postactions);
523
        }
524
 
525
        $viewactions = stats_get_action_names('view');
526
 
527
        foreach ($baseviewactions as $action) {
528
            $this->assertContains($action, $viewactions);
529
        }
530
    }
531
 
532
    /**
533
     * Test the temporary table creation and deletion.
534
     */
11 efrain 535
    public function test_statslib_temp_table_create_and_drop(): void {
1 efrain 536
        global $DB;
537
 
538
        foreach ($this->tables as $table) {
539
            $this->assertFalse($DB->get_manager()->table_exists($table));
540
        }
541
 
542
        stats_temp_table_create();
543
 
544
        foreach ($this->tables as $table) {
545
            $this->assertTrue($DB->get_manager()->table_exists($table));
546
        }
547
 
548
        stats_temp_table_drop();
549
 
550
        foreach ($this->tables as $table) {
551
            $this->assertFalse($DB->get_manager()->table_exists($table));
552
        }
553
    }
554
 
555
    /**
556
     * Test the temporary table creation and deletion.
557
     *
558
     * @depends test_statslib_temp_table_create_and_drop
559
     */
11 efrain 560
    public function test_statslib_temp_table_fill(): void {
1 efrain 561
        global $CFG, $DB, $USER;
562
 
563
        $dataset = $this->load_xml_data_file(__DIR__."/fixtures/statslib-test09.xml");
564
        $this->prepare_db($dataset, array('log'));
565
 
566
        // This nonsense needs to be rewritten.
567
        $date = new \DateTime('now', \core_date::get_server_timezone_object());
568
        $start = self::DAY - $date->getOffset();
569
        $end   = $start + (24 * 3600);
570
 
571
        stats_temp_table_create();
572
        stats_temp_table_fill($start, $end);
573
 
574
        $this->assertEquals(1, $DB->count_records('temp_log1'));
575
        $this->assertEquals(1, $DB->count_records('temp_log2'));
576
 
577
        stats_temp_table_drop();
578
 
579
        // New log stores.
580
        $this->preventResetByRollback();
581
        stats_temp_table_create();
582
 
583
        $course = $this->getDataGenerator()->create_course();
584
        $context = \context_course::instance($course->id);
585
        $fcontext = \context_course::instance(SITEID);
586
        $user = $this->getDataGenerator()->create_user();
587
        $this->setUser($user);
588
 
589
        $this->assertFileExists("$CFG->dirroot/$CFG->admin/tool/log/store/standard/version.php");
590
        set_config('enabled_stores', 'logstore_standard', 'tool_log');
591
        set_config('buffersize', 0, 'logstore_standard');
592
        set_config('logguests', 1, 'logstore_standard');
593
        get_log_manager(true);
594
 
595
        $DB->delete_records('logstore_standard_log');
596
 
597
        \core_tests\event\create_executed::create(array('context' => $fcontext, 'courseid' => SITEID))->trigger();
598
        \core_tests\event\read_executed::create(array('context' => $context, 'courseid' => $course->id))->trigger();
599
        \core_tests\event\update_executed::create(array('context' => \context_system::instance()))->trigger();
600
        \core_tests\event\delete_executed::create(array('context' => \context_system::instance()))->trigger();
601
 
602
        \core\event\user_loggedin::create(
603
            array(
604
                'userid' => $USER->id,
605
                'objectid' => $USER->id,
606
                'other' => array('username' => $USER->username),
607
            )
608
        )->trigger();
609
 
610
        $DB->set_field('logstore_standard_log', 'timecreated', 10);
611
 
612
        $this->assertEquals(5, $DB->count_records('logstore_standard_log'));
613
 
614
        \core_tests\event\delete_executed::create(array('context' => \context_system::instance()))->trigger();
615
        \core_tests\event\delete_executed::create(array('context' => \context_system::instance()))->trigger();
616
 
617
        // Fake the origin of events.
618
        $DB->set_field('logstore_standard_log', 'origin', 'web', array());
619
 
620
        $this->assertEquals(7, $DB->count_records('logstore_standard_log'));
621
 
622
        stats_temp_table_fill(9, 11);
623
 
624
        $logs1 = $DB->get_records('temp_log1');
625
        $logs2 = $DB->get_records('temp_log2');
626
        $this->assertCount(5, $logs1);
627
        $this->assertCount(5, $logs2);
628
        // The order of records in the temp tables is not guaranteed...
629
 
630
        $viewcount = 0;
631
        $updatecount = 0;
632
        $logincount = 0;
633
        foreach ($logs1 as $log) {
634
            if ($log->course == $course->id) {
635
                $this->assertEquals('view', $log->action);
636
                $viewcount++;
637
            } else {
638
                $this->assertTrue(in_array($log->action, array('update', 'login')));
639
                if ($log->action === 'update') {
640
                    $updatecount++;
641
                } else {
642
                    $logincount++;
643
                }
644
                $this->assertEquals(SITEID, $log->course);
645
            }
646
            $this->assertEquals($user->id, $log->userid);
647
        }
648
        $this->assertEquals(1, $viewcount);
649
        $this->assertEquals(3, $updatecount);
650
        $this->assertEquals(1, $logincount);
651
 
652
        set_config('enabled_stores', '', 'tool_log');
653
        get_log_manager(true);
654
        stats_temp_table_drop();
655
    }
656
 
657
    /**
658
     * Test the temporary table creation and deletion.
659
     *
660
     * @depends test_statslib_temp_table_create_and_drop
661
     */
11 efrain 662
    public function test_statslib_temp_table_setup(): void {
1 efrain 663
        global $DB;
664
 
665
        $DB->delete_records('log');
666
 
667
        stats_temp_table_create();
668
        stats_temp_table_setup();
669
 
670
        $this->assertEquals(1, $DB->count_records('temp_enroled'));
671
 
672
        stats_temp_table_drop();
673
    }
674
 
675
    /**
676
     * Test the function that clean out the temporary tables.
677
     *
678
     * @depends test_statslib_temp_table_create_and_drop
679
     */
11 efrain 680
    public function test_statslib_temp_table_clean(): void {
1 efrain 681
        global $DB;
682
 
683
        $rows = array(
684
            'temp_log1'             => array('id' => 1, 'course' => 1),
685
            'temp_log2'             => array('id' => 1, 'course' => 1),
686
            'temp_stats_daily'      => array('id' => 1, 'courseid' => 1),
687
            'temp_stats_user_daily' => array('id' => 1, 'courseid' => 1),
688
        );
689
 
690
        stats_temp_table_create();
691
 
692
        foreach ($rows as $table => $row) {
693
            $DB->insert_record_raw($table, $row);
694
            $this->assertEquals(1, $DB->count_records($table));
695
        }
696
 
697
        stats_temp_table_clean();
698
 
699
        foreach ($rows as $table => $row) {
700
            $this->assertEquals(0, $DB->count_records($table));
701
        }
702
 
703
        $this->assertEquals(1, $DB->count_records('stats_daily'));
704
        $this->assertEquals(1, $DB->count_records('stats_user_daily'));
705
 
706
        stats_temp_table_drop();
707
    }
708
 
709
    /**
710
     * Test the daily stats function.
711
     *
712
     * @depends test_statslib_get_base_daily
713
     * @depends test_statslib_get_next_day_start
714
     * @depends test_statslib_get_start_from
715
     * @depends test_statslib_temp_table_create_and_drop
716
     * @depends test_statslib_temp_table_setup
717
     * @depends test_statslib_temp_table_fill
718
     * @dataProvider daily_log_provider
719
     */
11 efrain 720
    public function test_statslib_cron_daily($xmlfile): void {
1 efrain 721
        global $CFG, $DB;
722
 
723
        $dataset = $this->load_xml_data_file(__DIR__."/fixtures/{$xmlfile}");
724
        $stats = $this->prepare_db($dataset, array('log'));
725
        $stats = $dataset->get_rows(['stats_daily', 'stats_user_daily']);
726
 
727
        // Stats cron daily uses mtrace, turn on buffering to silence output.
728
        ob_start();
729
        stats_cron_daily(1);
730
        $output = ob_get_contents();
731
        ob_end_clean();
732
 
733
        $this->verify_stats($stats, $output);
734
    }
735
 
736
    /**
737
     * Test the daily stats function.
738
     *
739
     * @depends test_statslib_get_base_daily
740
     * @depends test_statslib_get_next_day_start
741
     */
11 efrain 742
    public function test_statslib_cron_daily_no_default_profile_id(): void {
1 efrain 743
        global $CFG, $DB;
744
        $CFG->defaultfrontpageroleid = 0;
745
 
746
        $course1  = $DB->get_record('course', array('shortname' => 'course1'));
747
        $guestid  = $CFG->siteguest;
748
        $start    = stats_get_base_daily(1272758400);
749
        $end      = stats_get_next_day_start($start);
750
        $fpid     = (int) $CFG->defaultfrontpageroleid;
751
        $gr       = get_guest_role();
752
 
753
        $dataset = $this->load_xml_data_file(__DIR__."/fixtures/statslib-test10.xml");
754
        $this->prepare_db($dataset, array('log'));
755
        $stats = $dataset->get_rows(['stats_user_daily']);
756
 
757
        // Stats cron daily uses mtrace, turn on buffering to silence output.
758
        ob_start();
759
        stats_cron_daily($maxdays=1);
760
        $output = ob_get_contents();
761
        ob_end_clean();
762
 
763
        $this->verify_stats($dataset, $output);
764
    }
765
}