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_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
28
 */
29
class progress_test extends \advanced_testcase {
30
 
31
    /**
32
     * Test setup.
33
     */
34
    public function setUp(): void {
35
        global $CFG;
36
 
37
        $CFG->enablecompletion = true;
38
        $this->resetAfterTest();
39
    }
40
 
41
    /**
42
     * Tests that the course progress percentage is returned correctly when we have only activity completion.
43
     */
11 efrain 44
    public function test_course_progress_percentage_with_just_activities(): void {
1 efrain 45
        global $DB;
46
 
47
        // Add a course that supports completion.
48
        $course = $this->getDataGenerator()->create_course(array('enablecompletion' => 1));
49
 
50
        // Enrol a user in the course.
51
        $user = $this->getDataGenerator()->create_user();
52
        $studentrole = $DB->get_record('role', array('shortname' => 'student'));
53
        $this->getDataGenerator()->enrol_user($user->id, $course->id, $studentrole->id);
54
 
55
        // Add four activities that use completion.
56
        $assign = $this->getDataGenerator()->create_module('assign', array('course' => $course->id),
57
            array('completion' => 1));
58
        $data = $this->getDataGenerator()->create_module('data', array('course' => $course->id),
59
            array('completion' => 1));
60
        $this->getDataGenerator()->create_module('forum', array('course' => $course->id),
61
            array('completion' => 1));
62
        $this->getDataGenerator()->create_module('forum', array('course' => $course->id),
63
            array('completion' => 1));
64
 
65
        // Add an activity that does *not* use completion.
66
        $this->getDataGenerator()->create_module('assign', array('course' => $course->id));
67
 
68
        // Mark two of them as completed for a user.
69
        $cmassign = get_coursemodule_from_id('assign', $assign->cmid);
70
        $cmdata = get_coursemodule_from_id('data', $data->cmid);
71
        $completion = new \completion_info($course);
72
        $completion->update_state($cmassign, COMPLETION_COMPLETE, $user->id);
73
        $completion->update_state($cmdata, COMPLETION_COMPLETE, $user->id);
74
 
75
        // Check we have received valid data.
76
        // Note - only 4 out of the 5 activities support completion, and the user has completed 2 of those.
77
        $this->assertEquals('50', \core_completion\progress::get_course_progress_percentage($course, $user->id));
78
    }
79
 
80
    /**
81
     * Tests that the course progress percentage is returned correctly when we have a course and activity completion.
82
     */
11 efrain 83
    public function test_course_progress_percentage_with_activities_and_course(): void {
1 efrain 84
        global $DB;
85
 
86
        // Add a course that supports completion.
87
        $course = $this->getDataGenerator()->create_course(array('enablecompletion' => 1));
88
 
89
        // Enrol a user in the course.
90
        $user = $this->getDataGenerator()->create_user();
91
        $studentrole = $DB->get_record('role', array('shortname' => 'student'));
92
        $this->getDataGenerator()->enrol_user($user->id, $course->id, $studentrole->id);
93
 
94
        // Add four activities that use completion.
95
        $assign = $this->getDataGenerator()->create_module('assign', array('course' => $course->id),
96
            array('completion' => 1));
97
        $data = $this->getDataGenerator()->create_module('data', array('course' => $course->id),
98
            array('completion' => 1));
99
        $this->getDataGenerator()->create_module('forum', array('course' => $course->id),
100
            array('completion' => 1));
101
        $this->getDataGenerator()->create_module('forum', array('course' => $course->id),
102
            array('completion' => 1));
103
 
104
        // Add an activity that does *not* use completion.
105
        $this->getDataGenerator()->create_module('assign', array('course' => $course->id));
106
 
107
        // Mark two of them as completed for a user.
108
        $cmassign = get_coursemodule_from_id('assign', $assign->cmid);
109
        $cmdata = get_coursemodule_from_id('data', $data->cmid);
110
        $completion = new \completion_info($course);
111
        $completion->update_state($cmassign, COMPLETION_COMPLETE, $user->id);
112
        $completion->update_state($cmdata, COMPLETION_COMPLETE, $user->id);
113
 
114
        // Now, mark the course as completed.
115
        $ccompletion = new completion_completion(array('course' => $course->id, 'userid' => $user->id));
116
        $ccompletion->mark_complete();
117
 
118
        // Check we have received valid data.
119
        // The course completion takes priority, so should return 100.
120
        $this->assertEquals('100', \core_completion\progress::get_course_progress_percentage($course, $user->id));
121
    }
122
 
123
    /**
124
     * Tests that the course progress percentage is returned correctly for various grade to pass settings
125
     *
126
     * @covers \core_completion\progress::get_course_progress_percentage.
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
}