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_analytics;
18
 
19
defined('MOODLE_INTERNAL') || die();
20
 
21
require_once(__DIR__ . '/fixtures/test_indicator_max.php');
22
require_once(__DIR__ . '/fixtures/test_target_shortname.php');
23
 
24
/**
25
 * Unit tests for prediction actions.
26
 *
27
 * @package   core_analytics
28
 * @copyright 2017 David Monllaó {@link http://www.davidmonllao.com}
29
 * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
30
 */
31
class prediction_actions_test extends \advanced_testcase {
32
 
33
    /** @var model Store Model. */
34
    protected $model;
35
 
36
    /** @var \stdClass Store model object. */
37
    protected $modelobj;
38
 
39
    /** @var \stdClass Course 1 record. */
40
    protected $course1;
41
 
42
    /** @var \stdClass Course 2 record. */
43
    protected $course2;
44
 
45
    /** @var \context_course Store Model. */
46
    protected $context;
47
 
48
    /** @var \stdClass Teacher 1 user record. */
49
    protected $teacher1;
50
 
51
    /** @var \stdClass Teacher 2 user record. */
52
    protected $teacher2;
53
 
54
    /** @var \stdClass Teacher 3 user record. */
55
    protected $teacher3;
56
 
57
    /**
58
     * Common startup tasks
59
     */
60
    public function setUp(): void {
61
        global $DB;
62
 
63
        $this->setAdminUser();
64
        $target = \core_analytics\manager::get_target('test_target_shortname');
65
        $indicators = array('test_indicator_max');
66
        foreach ($indicators as $key => $indicator) {
67
            $indicators[$key] = \core_analytics\manager::get_indicator($indicator);
68
        }
69
 
70
        $this->model = \core_analytics\model::create($target, $indicators);
71
        $this->modelobj = $this->model->get_model_obj();
72
        $this->model->enable('\core\analytics\time_splitting\single_range');
73
 
74
        $this->resetAfterTest(true);
75
 
76
        $this->course1 = $this->getDataGenerator()->create_course();
77
        $this->course2 = $this->getDataGenerator()->create_course();
78
        $this->context = \context_course::instance($this->course1->id);
79
 
80
        $this->teacher1 = $this->getDataGenerator()->create_user();
81
        $this->teacher2 = $this->getDataGenerator()->create_user();
82
        $this->teacher3 = $this->getDataGenerator()->create_user();
83
 
84
        $this->getDataGenerator()->enrol_user($this->teacher1->id, $this->course1->id, 'editingteacher');
85
        $this->getDataGenerator()->enrol_user($this->teacher2->id, $this->course1->id, 'editingteacher');
86
        $this->getDataGenerator()->enrol_user($this->teacher3->id, $this->course1->id, 'editingteacher');
87
 
88
        // The only relevant fields are modelid, contextid and sampleid. I'm cheating and setting
89
        // contextid as the course context so teachers can access these predictions.
90
        $pred = new \stdClass();
91
        $pred->modelid = $this->model->get_id();
92
        $pred->contextid = $this->context->id;
93
        $pred->sampleid = $this->course1->id;
94
        $pred->rangeindex = 1;
95
        $pred->prediction = 1;
96
        $pred->predictionscore = 1;
97
        $pred->calculations = json_encode(array('test_indicator_max' => 1));
98
        $pred->timecreated = time();
99
        $DB->insert_record('analytics_predictions', $pred);
100
 
101
        $pred->sampleid = $this->course2->id;
102
        $DB->insert_record('analytics_predictions', $pred);
103
    }
104
 
105
    /**
106
     * test_get_predictions
107
     */
11 efrain 108
    public function test_action_executed(): void {
1 efrain 109
        global $DB;
110
 
111
        $this->assertEquals(0, $DB->count_records('analytics_prediction_actions'));
112
 
113
        // Teacher 2 flags a prediction (it doesn't matter which one) as fixed.
114
        $this->setUser($this->teacher2);
115
        list($ignored, $predictions) = $this->model->get_predictions($this->context, true);
116
        $prediction = reset($predictions);
117
        $prediction->action_executed(\core_analytics\prediction::ACTION_FIXED, $this->model->get_target());
118
 
119
        $recordset = $this->model->get_prediction_actions($this->context);
120
        $this->assertCount(1, $recordset);
121
        $recordset->close();
122
        $this->assertEquals(1, $DB->count_records('analytics_prediction_actions'));
123
        $action = $DB->get_record('analytics_prediction_actions', array('userid' => $this->teacher2->id));
124
        $this->assertEquals(\core_analytics\prediction::ACTION_FIXED, $action->actionname);
125
 
126
        $prediction->action_executed(\core_analytics\prediction::ACTION_INCORRECTLY_FLAGGED, $this->model->get_target());
127
        $recordset = $this->model->get_prediction_actions($this->context);
128
        $this->assertCount(2, $recordset);
129
        $recordset->close();
130
        $this->assertEquals(2, $DB->count_records('analytics_prediction_actions'));
131
    }
132
 
133
    /**
134
     * Data provider for test_get_executed_actions.
135
     *
136
     * @return  array
137
     */
138
    public function execute_actions_provider(): array {
139
        return [
140
            'Empty actions with no filter' => [
141
                [],
142
                [],
143
 
144
            ],
145
            'Empty actions with filter' => [
146
                [],
147
                [\core_analytics\prediction::ACTION_FIXED],
148
 
149
            ],
150
            'Multiple actions with no filter' => [
151
                [
152
                    \core_analytics\prediction::ACTION_FIXED,
153
                    \core_analytics\prediction::ACTION_FIXED,
154
                    \core_analytics\prediction::ACTION_INCORRECTLY_FLAGGED
155
                ],
156
                [],
157
                3
158
            ],
159
            'Multiple actions applying filter' => [
160
                [
161
                    \core_analytics\prediction::ACTION_FIXED,
162
                    \core_analytics\prediction::ACTION_FIXED,
163
                    \core_analytics\prediction::ACTION_INCORRECTLY_FLAGGED
164
                ],
165
                [\core_analytics\prediction::ACTION_FIXED],
166
                2
167
            ],
168
            'Multiple actions not applying filter' => [
169
                [
170
                    \core_analytics\prediction::ACTION_FIXED,
171
                    \core_analytics\prediction::ACTION_FIXED,
172
                    \core_analytics\prediction::ACTION_INCORRECTLY_FLAGGED
173
                ],
174
                [\core_analytics\prediction::ACTION_NOT_APPLICABLE],
175
 
176
            ],
177
            'Multiple actions with multiple filter' => [
178
                [
179
                    \core_analytics\prediction::ACTION_FIXED,
180
                    \core_analytics\prediction::ACTION_FIXED,
181
                    \core_analytics\prediction::ACTION_INCORRECTLY_FLAGGED
182
                ],
183
                [\core_analytics\prediction::ACTION_FIXED, \core_analytics\prediction::ACTION_INCORRECTLY_FLAGGED],
184
                3
185
            ],
186
        ];
187
    }
188
 
189
    /**
190
     * Tests for get_executed_actions() function.
191
     *
192
     * @dataProvider    execute_actions_provider
193
     * @param   array   $actionstoexecute    An array of actions to execute
194
     * @param   array   $actionnamefilter   Actions to filter
195
     * @param   int     $returned             Number of actions returned
196
     *
197
     * @covers \core_analytics\prediction::get_executed_actions
198
     */
11 efrain 199
    public function test_get_executed_actions(array $actionstoexecute, array $actionnamefilter, int $returned): void {
1 efrain 200
 
201
        $this->setUser($this->teacher2);
202
        list($ignored, $predictions) = $this->model->get_predictions($this->context, true);
203
        $prediction = reset($predictions);
204
        $target = $this->model->get_target();
205
        foreach($actionstoexecute as $action) {
206
            $prediction->action_executed($action, $target);
207
        }
208
 
209
        $filteredactions = $prediction->get_executed_actions($actionnamefilter);
210
        $this->assertCount($returned, $filteredactions);
211
    }
212
 
213
    /**
214
     * test_get_predictions
215
     */
11 efrain 216
    public function test_get_predictions(): void {
1 efrain 217
        global $DB;
218
 
219
        // Already logged in as admin.
220
        list($ignored, $predictions) = $this->model->get_predictions($this->context, true);
221
        $this->assertCount(2, $predictions);
222
 
223
        $this->setUser($this->teacher1);
224
        list($ignored, $predictions) = $this->model->get_predictions($this->context, true);
225
        $this->assertCount(2, $predictions);
226
 
227
        $this->setUser($this->teacher2);
228
        list($ignored, $predictions) = $this->model->get_predictions($this->context, false);
229
        $this->assertCount(2, $predictions);
230
 
231
        // Teacher 2 flags a prediction (it doesn't matter which one).
232
        $prediction = reset($predictions);
233
        $prediction->action_executed(\core_analytics\prediction::ACTION_FIXED, $this->model->get_target());
234
        $prediction->action_executed(\core_analytics\prediction::ACTION_NOT_APPLICABLE, $this->model->get_target());
235
        $prediction->action_executed(\core_analytics\prediction::ACTION_INCORRECTLY_FLAGGED, $this->model->get_target());
236
 
237
        $recordset = $this->model->get_prediction_actions($this->context);
238
        $this->assertCount(3, $recordset);
239
        $recordset->close();
240
 
241
        list($ignored, $predictions) = $this->model->get_predictions($this->context, true);
242
        $this->assertCount(1, $predictions);
243
        list($ignored, $predictions) = $this->model->get_predictions($this->context, false);
244
        $this->assertCount(2, $predictions);
245
 
246
        // Teacher 1 can still see both predictions.
247
        $this->setUser($this->teacher1);
248
        list($ignored, $predictions) = $this->model->get_predictions($this->context, true);
249
        $this->assertCount(2, $predictions);
250
        list($ignored, $predictions) = $this->model->get_predictions($this->context, false);
251
        $this->assertCount(2, $predictions);
252
 
253
        $recordset = $this->model->get_prediction_actions($this->context);
254
        $this->assertCount(3, $recordset);
255
        $recordset->close();
256
 
257
        // Trying with a deleted course.
258
        $DB->delete_records('course', ['id' => $this->course2->id]);
259
        $this->setUser($this->teacher3);
260
        list($ignored, $predictions) = $this->model->get_predictions($this->context);
261
        $this->assertCount(1, $predictions);
262
        reset($predictions)->action_executed(\core_analytics\prediction::ACTION_FIXED, $this->model->get_target());
263
        $this->assertEmpty($this->model->get_predictions($this->context));
264
    }
265
}