MDL-64477 analytics: Introduce a new \core_analytics\stats class
[moodle.git] / analytics / tests / stats_test.php
blobd92f40375cbb7078b5494cc27631c3f54005c4f7
1 <?php
2 // This file is part of Moodle - https://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.
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 * Provides the {@link analytics_stats_testcase} class.
20 * @package core_analytics
21 * @category test
22 * @copyright 2019 David Mudrák <david@moodle.com>
23 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
26 defined('MOODLE_INTERNAL') || die();
28 require_once(__DIR__ . '/fixtures/test_indicator_fullname.php');
29 require_once(__DIR__ . '/fixtures/test_target_shortname.php');
31 /**
32 * Unit tests for the analytics stats.
34 * @copyright 2019 David Mudrák <david@moodle.com>
35 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
37 class analytics_stats_testcase extends advanced_testcase {
39 /**
40 * Set up the test environment.
42 public function setUp() {
44 $this->setAdminUser();
47 /**
48 * Test the {@link \core_analytics\stats::enabled_models()} implementation.
50 public function test_enabled_models() {
52 $this->resetAfterTest(true);
54 // By default, sites have {@link \core\analytics\target\no_teaching} enabled.
55 $this->assertEquals(1, \core_analytics\stats::enabled_models());
57 $model = \core_analytics\model::create(
58 \core_analytics\manager::get_target('\core\analytics\target\course_dropout'),
60 \core_analytics\manager::get_indicator('\core\analytics\indicator\any_write_action'),
64 // Purely adding a new model does not make it included in the stats.
65 $this->assertEquals(1, \core_analytics\stats::enabled_models());
67 // New models must be enabled to have them counted.
68 $model->enable('\core\analytics\time_splitting\quarters');
69 $this->assertEquals(2, \core_analytics\stats::enabled_models());
72 /**
73 * Test the {@link \core_analytics\stats::predictions()} implementation.
75 public function test_predictions() {
77 $this->resetAfterTest(true);
79 $model = \core_analytics\model::create(
80 \core_analytics\manager::get_target('test_target_shortname'),
82 \core_analytics\manager::get_indicator('test_indicator_fullname'),
86 $model->enable('\core\analytics\time_splitting\no_splitting');
88 // Train the model.
89 $this->getDataGenerator()->create_course(['shortname' => 'a', 'fullname' => 'a', 'visible' => 1]);
90 $this->getDataGenerator()->create_course(['shortname' => 'b', 'fullname' => 'b', 'visible' => 1]);
91 $model->train();
93 // No predictions yet.
94 $this->assertEquals(0, \core_analytics\stats::predictions());
96 // Get one new prediction.
97 $this->getDataGenerator()->create_course(['shortname' => 'aa', 'fullname' => 'aa', 'visible' => 0]);
98 $result = $model->predict();
100 $this->assertEquals(1, count($result->predictions));
101 $this->assertEquals(1, \core_analytics\stats::predictions());
103 // Nothing changes if there is no new prediction.
104 $result = $model->predict();
105 $this->assertFalse(isset($result->predictions));
106 $this->assertEquals(1, \core_analytics\stats::predictions());
108 // Get two more predictions, we have three in total now.
109 $this->getDataGenerator()->create_course(['shortname' => 'bb', 'fullname' => 'bb', 'visible' => 0]);
110 $this->getDataGenerator()->create_course(['shortname' => 'cc', 'fullname' => 'cc', 'visible' => 0]);
112 $result = $model->predict();
113 $this->assertEquals(2, count($result->predictions));
114 $this->assertEquals(3, \core_analytics\stats::predictions());
118 * Test the {@link \core_analytics\stats::actions()} and {@link \core_analytics\stats::actions_not_useful()} implementation.
120 public function test_actions() {
121 global $DB;
122 $this->resetAfterTest(true);
124 $model = \core_analytics\model::create(
125 \core_analytics\manager::get_target('test_target_shortname'),
127 \core_analytics\manager::get_indicator('test_indicator_fullname'),
131 $model->enable('\core\analytics\time_splitting\no_splitting');
133 // Train the model.
134 $this->getDataGenerator()->create_course(['shortname' => 'a', 'fullname' => 'a', 'visible' => 1]);
135 $this->getDataGenerator()->create_course(['shortname' => 'b', 'fullname' => 'b', 'visible' => 1]);
136 $model->train();
138 // Generate two predictions.
139 $this->getDataGenerator()->create_course(['shortname' => 'aa', 'fullname' => 'aa', 'visible' => 0]);
140 $this->getDataGenerator()->create_course(['shortname' => 'bb', 'fullname' => 'bb', 'visible' => 0]);
141 $model->predict();
143 list($p1, $p2) = array_values($DB->get_records('analytics_predictions'));
145 $p1 = new \core_analytics\prediction($p1, []);
146 $p2 = new \core_analytics\prediction($p2, []);
148 // No actions executed at the start.
149 $this->assertEquals(0, \core_analytics\stats::actions());
150 $this->assertEquals(0, \core_analytics\stats::actions_not_useful());
152 // The user has acknowledged the first prediction.
153 $p1->action_executed(\core_analytics\prediction::ACTION_FIXED, $model->get_target());
154 $this->assertEquals(1, \core_analytics\stats::actions());
155 $this->assertEquals(0, \core_analytics\stats::actions_not_useful());
157 // The user has marked the other prediction as not useful.
158 $p2->action_executed(\core_analytics\prediction::ACTION_NOT_USEFUL, $model->get_target());
159 $this->assertEquals(2, \core_analytics\stats::actions());
160 $this->assertEquals(1, \core_analytics\stats::actions_not_useful());