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_completion;
18
 
19
use completion_completion;
20
 
21
/**
22
 * Test completion progress API.
23
 *
24
 * @package core_completion
25
 * @category test
26
 * @copyright 2017 Mark Nelson <markn@moodle.com>
27
 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
1441 ariadna 28
 * @covers \core_completion\progress
1 efrain 29
 */
1441 ariadna 30
final class progress_test extends \advanced_testcase {
1 efrain 31
 
32
    /**
33
     * Test setup.
34
     */
35
    public function setUp(): void {
36
        global $CFG;
1441 ariadna 37
        parent::setUp();
1 efrain 38
 
39
        $CFG->enablecompletion = true;
40
        $this->resetAfterTest();
41
    }
42
 
43
    /**
44
     * Tests that the course progress percentage is returned correctly when we have only activity completion.
45
     */
11 efrain 46
    public function test_course_progress_percentage_with_just_activities(): void {
1 efrain 47
        global $DB;
48
 
49
        // Add a course that supports completion.
50
        $course = $this->getDataGenerator()->create_course(array('enablecompletion' => 1));
51
 
52
        // Enrol a user in the course.
53
        $user = $this->getDataGenerator()->create_user();
54
        $studentrole = $DB->get_record('role', array('shortname' => 'student'));
55
        $this->getDataGenerator()->enrol_user($user->id, $course->id, $studentrole->id);
56
 
57
        // Add four activities that use completion.
58
        $assign = $this->getDataGenerator()->create_module('assign', array('course' => $course->id),
59
            array('completion' => 1));
60
        $data = $this->getDataGenerator()->create_module('data', array('course' => $course->id),
61
            array('completion' => 1));
62
        $this->getDataGenerator()->create_module('forum', array('course' => $course->id),
63
            array('completion' => 1));
64
        $this->getDataGenerator()->create_module('forum', array('course' => $course->id),
65
            array('completion' => 1));
66
 
67
        // Add an activity that does *not* use completion.
68
        $this->getDataGenerator()->create_module('assign', array('course' => $course->id));
69
 
70
        // Mark two of them as completed for a user.
71
        $cmassign = get_coursemodule_from_id('assign', $assign->cmid);
72
        $cmdata = get_coursemodule_from_id('data', $data->cmid);
73
        $completion = new \completion_info($course);
74
        $completion->update_state($cmassign, COMPLETION_COMPLETE, $user->id);
75
        $completion->update_state($cmdata, COMPLETION_COMPLETE, $user->id);
76
 
77
        // Check we have received valid data.
78
        // Note - only 4 out of the 5 activities support completion, and the user has completed 2 of those.
79
        $this->assertEquals('50', \core_completion\progress::get_course_progress_percentage($course, $user->id));
80
    }
81
 
82
    /**
83
     * Tests that the course progress percentage is returned correctly when we have a course and activity completion.
84
     */
11 efrain 85
    public function test_course_progress_percentage_with_activities_and_course(): void {
1 efrain 86
        global $DB;
87
 
88
        // Add a course that supports completion.
89
        $course = $this->getDataGenerator()->create_course(array('enablecompletion' => 1));
90
 
91
        // Enrol a user in the course.
92
        $user = $this->getDataGenerator()->create_user();
93
        $studentrole = $DB->get_record('role', array('shortname' => 'student'));
94
        $this->getDataGenerator()->enrol_user($user->id, $course->id, $studentrole->id);
95
 
96
        // Add four activities that use completion.
97
        $assign = $this->getDataGenerator()->create_module('assign', array('course' => $course->id),
98
            array('completion' => 1));
99
        $data = $this->getDataGenerator()->create_module('data', array('course' => $course->id),
100
            array('completion' => 1));
101
        $this->getDataGenerator()->create_module('forum', array('course' => $course->id),
102
            array('completion' => 1));
103
        $this->getDataGenerator()->create_module('forum', array('course' => $course->id),
104
            array('completion' => 1));
105
 
106
        // Add an activity that does *not* use completion.
107
        $this->getDataGenerator()->create_module('assign', array('course' => $course->id));
108
 
109
        // Mark two of them as completed for a user.
110
        $cmassign = get_coursemodule_from_id('assign', $assign->cmid);
111
        $cmdata = get_coursemodule_from_id('data', $data->cmid);
112
        $completion = new \completion_info($course);
113
        $completion->update_state($cmassign, COMPLETION_COMPLETE, $user->id);
114
        $completion->update_state($cmdata, COMPLETION_COMPLETE, $user->id);
115
 
116
        // Now, mark the course as completed.
117
        $ccompletion = new completion_completion(array('course' => $course->id, 'userid' => $user->id));
118
        $ccompletion->mark_complete();
119
 
120
        // Check we have received valid data.
121
        // The course completion takes priority, so should return 100.
122
        $this->assertEquals('100', \core_completion\progress::get_course_progress_percentage($course, $user->id));
123
    }
124
 
125
    /**
126
     * Tests that the course progress percentage is returned correctly for various grade to pass settings
127
     */
11 efrain 128
    public function test_course_progress_percentage_completion_state(): void {
1 efrain 129
        global $DB, $CFG;
130
 
131
        require_once("{$CFG->dirroot}/completion/criteria/completion_criteria_activity.php");
132
 
133
        // Add a course that supports completion.
134
        $course = $this->getDataGenerator()->create_course(['enablecompletion' => 1]);
135
 
136
        // Enrol a user in the course.
137
        $teacher = $this->getDataGenerator()->create_user();
138
        $user = $this->getDataGenerator()->create_user();
139
        $studentrole = $DB->get_record('role', ['shortname' => 'student']);
140
        $teacherrole = $DB->get_record('role', array('shortname' => 'editingteacher'));
141
        $this->getDataGenerator()->enrol_user($user->id, $course->id, $studentrole->id);
142
        $this->getDataGenerator()->enrol_user($teacher->id, $course->id, $teacherrole->id);
143
 
144
        // Add three activities that use completion.
145
        /** @var \mod_assign_generator $assigngenerator */
146
        $assigngenerator = $this->getDataGenerator()->get_plugin_generator('mod_assign');
147
        $assign['passgragepassed'] = $assigngenerator->create_instance([
148
            'course' => $course->id,
149
            'completion' => COMPLETION_ENABLED,
150
            'completionusegrade' => 1,
151
            'gradepass' => 50,
152
            'completionpassgrade' => 1
153
        ]);
154
 
155
        $assign['passgragefailed'] = $assigngenerator->create_instance([
156
            'course' => $course->id,
157
            'completion' => COMPLETION_ENABLED,
158
            'completionusegrade' => 1,
159
            'gradepass' => 50,
160
            'completionpassgrade' => 1
161
        ]);
162
 
163
        $assign['passgragenotused'] = $assigngenerator->create_instance([
164
            'course' => $course->id,
165
            'completion' => COMPLETION_ENABLED,
166
            'completionusegrade' => 1,
167
            'gradepass' => 50,
168
        ]);
169
 
170
        $assign['nograde'] = $assigngenerator->create_instance([
171
            'course' => $course->id,
172
            'completion' => COMPLETION_ENABLED,
173
        ]);
174
 
175
        $c = new \completion_info($course);
176
 
177
        foreach ($assign as $item) {
178
            $cmassing = get_coursemodule_from_id('assign', $item->cmid);
179
 
180
            // Add activity completion criteria.
181
            $criteriadata = new \stdClass();
182
            $criteriadata->id = $course->id;
183
            $criteriadata->criteria_activity = [];
184
            // Some activities.
185
            $criteriadata->criteria_activity[$cmassing->id] = 1;
186
            $criterion = new \completion_criteria_activity();
187
            $criterion->update_config($criteriadata);
188
        }
189
 
190
        $this->setUser($teacher);
191
 
192
        foreach ($assign as $key => $item) {
193
            $cm = get_coursemodule_from_instance('assign', $item->id);
194
 
195
            // Mark user completions.
196
            $completion = new \stdClass();
197
            $completion->coursemoduleid = $cm->id;
198
            $completion->timemodified = time();
199
            $completion->viewed = COMPLETION_NOT_VIEWED;
200
            $completion->overrideby = null;
201
 
202
            if ($key == 'passgragepassed') {
203
                $completion->id = 0;
204
                $completion->completionstate = COMPLETION_COMPLETE_PASS;
205
                $completion->userid = $user->id;
206
                $c->internal_set_data($cm, $completion, true);
207
            } else if ($key == 'passgragefailed') {
208
                $completion->id = 0;
209
                $completion->completionstate = COMPLETION_COMPLETE_FAIL;
210
                $completion->userid = $user->id;
211
                $c->internal_set_data($cm, $completion, true);
212
            } else if ($key == 'passgragenotused') {
213
                $completion->id = 0;
214
                $completion->completionstate = COMPLETION_COMPLETE;
215
                $completion->userid = $user->id;
216
                $c->internal_set_data($cm, $completion, true);
217
            } else if ($key == 'nograde') {
218
                $completion->id = 0;
219
                $completion->completionstate = COMPLETION_COMPLETE;
220
                $completion->userid = $user->id;
221
                $c->internal_set_data($cm, $completion, true);
222
            }
223
        }
224
 
225
        // Run course completions cron.
226
        \core_completion\api::mark_course_completions_activity_criteria();
227
 
228
        // Check we have received valid data.
229
        // Only assign2 is not completed.
230
        $this->assertEquals('75', \core_completion\progress::get_course_progress_percentage($course, $user->id));
231
    }
232
 
233
    /**
234
     * Tests that the course progress returns null when the course does not support it.
235
     */
11 efrain 236
    public function test_course_progress_course_not_using_completion(): void {
1 efrain 237
        // Create a course that does not use completion.
238
        $course = $this->getDataGenerator()->create_course();
239
 
240
        // Check that the result was null.
241
        $this->assertNull(\core_completion\progress::get_course_progress_percentage($course));
242
    }
243
 
244
    /**
245
     * Tests that the course progress returns null when there are no activities that support it.
246
     */
11 efrain 247
    public function test_course_progress_no_activities_using_completion(): void {
1 efrain 248
        // Create a course that does support completion.
249
        $course = $this->getDataGenerator()->create_course(array('enablecompletion' => 1));
250
 
251
        // Add an activity that does *not* support completion.
252
        $this->getDataGenerator()->create_module('assign', array('course' => $course->id));
253
 
254
        // Check that the result was null.
255
        $this->assertNull(\core_completion\progress::get_course_progress_percentage($course));
256
    }
257
 
258
    /**
259
     * Tests that the course progress returns null for a not tracked for completion user in a course.
260
     */
11 efrain 261
    public function test_course_progress_not_tracked_user(): void {
1 efrain 262
        global $DB;
263
 
264
        // Add a course that supports completion.
265
        $course = $this->getDataGenerator()->create_course(array('enablecompletion' => 1));
266
 
267
        // Enrol a user in the course.
268
        $user = $this->getDataGenerator()->create_user();
269
        $studentrole = $DB->get_record('role', array('shortname' => 'student'));
270
 
271
        $this->getDataGenerator()->enrol_user($user->id, $course->id, $studentrole->id);
272
 
273
        // Now, mark the course as completed.
274
        $ccompletion = new completion_completion(array('course' => $course->id, 'userid' => $user->id));
275
        $ccompletion->mark_complete();
276
 
277
        // The course completion should return 100.
278
        $this->assertEquals('100', \core_completion\progress::get_course_progress_percentage($course, $user->id));
279
 
280
        // Now make the user's role to be not tracked for completion.
281
        unassign_capability('moodle/course:isincompletionreports', $studentrole->id);
282
 
283
        // Check that the result is null now.
284
        $this->assertNull(\core_completion\progress::get_course_progress_percentage($course, $user->id));
285
    }
286
}