Proyectos de Subversion Moodle

Rev

| 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
/**
18
 * Overview table unit tests for block_completion_progress.
19
 *
20
 * @package    block_completion_progress
21
 * @copyright  2021 Jonathon Fowler <fowlerj@usq.edu.au>
22
 * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
23
 */
24
 
25
namespace block_completion_progress;
26
 
27
defined('MOODLE_INTERNAL') || die();
28
 
29
global $CFG;
30
require_once($CFG->dirroot . '/mod/assign/locallib.php');
31
require_once($CFG->dirroot.'/blocks/moodleblock.class.php');
32
require_once($CFG->dirroot.'/blocks/completion_progress/block_completion_progress.php');
33
 
34
use block_completion_progress\completion_progress;
35
use block_completion_progress\defaults;
36
 
37
/**
38
 * Overview table unit tests for block_completion_progress.
39
 *
40
 * @package    block_completion_progress
41
 * @copyright  2021 Jonathon Fowler <fowlerj@usq.edu.au>
42
 * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
43
 */
44
class overview_test extends \advanced_testcase {
45
    /**
46
     * Teacher users.
47
     * @var array
48
     */
49
    private $teachers = [];
50
 
51
    /**
52
     * Student users.
53
     * @var array
54
     */
55
    private $students = [];
56
 
57
    /**
58
     * Groups.
59
     * @var array
60
     */
61
    private $groups = [];
62
 
63
    /**
64
     * Number of students to create.
65
     */
66
    const STUDENT_COUNT = 4;
67
 
68
    /**
69
     * Create a course and add enrol users to it.
70
     */
71
    protected function setUp(): void {
72
        $this->resetAfterTest(true);
73
 
74
        set_config('enablecompletion', 1);
75
 
76
        $generator = $this->getDataGenerator();
77
 
78
        $this->course = $generator->create_course([
79
          'enablecompletion' => 1,
80
        ]);
81
 
82
        $this->teachers[0] = $generator->create_and_enrol($this->course, 'teacher');
83
 
84
        $this->groups[0] = $generator->create_group(['courseid' => $this->course->id]);
85
        $this->groups[1] = $generator->create_group(['courseid' => $this->course->id]);
86
 
87
        for ($i = 0; $i < self::STUDENT_COUNT; $i++) {
88
            $status = $i >= 3 ? ENROL_USER_SUSPENDED : null;
89
            $this->students[$i] = $generator->create_and_enrol($this->course, 'student',
90
                null, 'manual', 0, 0, $status);
91
 
92
            // Students are put into even/odd groups.
93
            $generator->create_group_member(['groupid' => $this->groups[$i % 2]->id,
94
                'userid' => $this->students[$i]->id]);
95
        }
96
    }
97
 
98
    /**
99
     * Convenience function to create a testable instance of an assignment.
100
     *
101
     * @param array $params Array of parameters to pass to the generator
102
     * @return assign Assign class.
103
     */
104
    protected function create_assign_instance($params) {
105
        $generator = $this->getDataGenerator()->get_plugin_generator('mod_assign');
106
        $params['course'] = $this->course->id;
107
        $instance = $generator->create_instance($params);
108
        $cm = get_coursemodule_from_instance('assign', $instance->id);
109
        $context = \context_module::instance($cm->id);
110
        return new \assign($context, $cm, $this->course);
111
    }
112
 
113
    /**
114
     * Test optional settings' effects on the overview table.
115
     * @covers \block_completion_progress\table\overview
116
     */
117
    public function test_overview_options() {
118
        global $DB, $PAGE;
119
 
120
        $output = $PAGE->get_renderer('block_completion_progress');
121
 
122
        // Add a block.
123
        $context = \context_course::instance($this->course->id);
124
        $blockinfo = [
125
            'parentcontextid' => $context->id,
126
            'pagetypepattern' => 'course-view-*',
127
            'showinsubcontexts' => 0,
128
            'defaultweight' => 5,
129
            'timecreated' => time(),
130
            'timemodified' => time(),
131
            'defaultregion' => 'side-post',
132
            'configdata' => base64_encode(serialize((object)[
133
                'orderby' => defaults::ORDERBY,
134
                'longbars' => defaults::LONGBARS,
135
                'progressBarIcons' => 0,    // Non-default.
136
                'showpercentage' => defaults::SHOWPERCENTAGE,
137
                'progressTitle' => "",
138
                'activitiesincluded' => defaults::ACTIVITIESINCLUDED,
139
            ])),
140
        ];
141
        $blockinstance = $this->getDataGenerator()->create_block('completion_progress', $blockinfo);
142
 
143
        $assign = $this->create_assign_instance([
144
          'submissiondrafts' => 0,
145
          'completionsubmit' => 1,
146
          'completion' => COMPLETION_TRACKING_AUTOMATIC
147
        ]);
148
 
149
        $PAGE->set_url('/');
150
 
151
        // Test inactive student is hidden and 'last in course' column is hidden.
152
        set_config('showinactive', 0, 'block_completion_progress');
153
        set_config('showlastincourse', 0, 'block_completion_progress');
154
        set_config('forceiconsinbar', 0, 'block_completion_progress');
155
        $progress = (new completion_progress($this->course))->for_overview()->for_block_instance($blockinstance);
156
        $table = new \block_completion_progress\table\overview($progress, [], 0, true);
157
        $table->define_baseurl('/');
158
 
159
        ob_start();
160
        $table->out(30, false);
161
        $text = ob_get_clean();
162
 
163
        $this->assertStringContainsString('<input id="user'.$this->students[0]->id.'" ', $text);
164
        $this->assertStringNotContainsString('<input id="user'.$this->students[3]->id.'" ', $text);
165
        $this->assertStringNotContainsString('col-timeaccess', $text);
166
        $this->assertStringNotContainsString('barWithIcons', $text);
167
 
168
        // Test inactive student is visible and 'last in course' column is shown.
169
        set_config('showinactive', 1, 'block_completion_progress');
170
        set_config('showlastincourse', 1, 'block_completion_progress');
171
        set_config('forceiconsinbar', 1, 'block_completion_progress');
172
        $progress = (new completion_progress($this->course))->for_overview()->for_block_instance($blockinstance);
173
        $table = new \block_completion_progress\table\overview($progress, [], 0, true);
174
        $table->define_baseurl('/');
175
 
176
        ob_start();
177
        $table->out(30, false);
178
        $text = ob_get_clean();
179
 
180
        $this->assertStringContainsString('<input id="user'.$this->students[0]->id.'" ', $text);
181
        $this->assertStringContainsString('<input id="user'.$this->students[3]->id.'" ', $text);
182
        $this->assertStringContainsString('col-timeaccess', $text);
183
        $this->assertStringContainsString('barWithIcons', $text);
184
 
185
        // Test that group filtering works.
186
        $progress = (new completion_progress($this->course))->for_overview()->for_block_instance($blockinstance);
187
        $table = new \block_completion_progress\table\overview($progress, [$this->groups[0]->id], 0, true);
188
        $table->define_baseurl('/');
189
 
190
        ob_start();
191
        $table->out(30, false);
192
        $text = ob_get_clean();
193
 
194
        $this->assertStringContainsString('<input id="user'.$this->students[0]->id.'" ', $text);
195
        $this->assertStringNotContainsString('<input id="user'.$this->students[1]->id.'" ', $text);
196
        $this->assertStringContainsString('<input id="user'.$this->students[2]->id.'" ', $text);
197
        $this->assertStringNotContainsString('<input id="user'.$this->students[3]->id.'" ', $text);
198
    }
199
 
200
    /**
201
     * Test that the overview table correctly sorts by progress.
202
     * @covers \block_completion_progress\table\overview
203
     */
204
    public function test_overview_percentage_sort() {
205
        global $DB, $PAGE;
206
 
207
        $PAGE->set_url('/');
208
        $output = $PAGE->get_renderer('block_completion_progress');
209
        $generator = $this->getDataGenerator();
210
 
211
        // Add a block.
212
        $context = \context_course::instance($this->course->id);
213
        $blockinfo = [
214
            'parentcontextid' => $context->id,
215
            'pagetypepattern' => 'course-view-*',
216
            'showinsubcontexts' => 0,
217
            'defaultweight' => 5,
218
            'timecreated' => time(),
219
            'timemodified' => time(),
220
            'defaultregion' => 'side-post',
221
            'configdata' => base64_encode(serialize((object)[
222
                'orderby' => defaults::ORDERBY,
223
                'longbars' => defaults::LONGBARS,
224
                'progressBarIcons' => 0,    // Non-default.
225
                'showpercentage' => defaults::SHOWPERCENTAGE,
226
                'progressTitle' => "",
227
                'activitiesincluded' => defaults::ACTIVITIESINCLUDED,
228
            ])),
229
        ];
230
        $blockinstance = $generator->create_block('completion_progress', $blockinfo);
231
 
232
        $page1 = $generator->create_module('page', [
233
            'course' => $this->course->id,
234
            'completion' => COMPLETION_TRACKING_MANUAL
235
        ]);
236
        $page1cm = get_coursemodule_from_id('page', $page1->cmid);
237
        $page2 = $generator->create_module('page', [
238
            'course' => $this->course->id,
239
            'completion' => COMPLETION_TRACKING_MANUAL
240
        ]);
241
        $page2cm = get_coursemodule_from_id('page', $page2->cmid);
242
 
243
        $completion = new \completion_info($this->course);
244
 
245
        // Set student 2 as having completed both pages.
246
        $completion->update_state($page1cm, COMPLETION_COMPLETE, $this->students[2]->id);
247
        $completion->update_state($page2cm, COMPLETION_COMPLETE, $this->students[2]->id);
248
 
249
        // Set student 0 as having completed one page.
250
        $completion->update_state($page1cm, COMPLETION_COMPLETE, $this->students[0]->id);
251
 
252
        $progress = (new completion_progress($this->course))->for_overview()->for_block_instance($blockinstance);
253
        $table = new \block_completion_progress\table\overview($progress, [], 0, true);
254
        $table->set_sortdata([['sortby' => 'progress', 'sortorder' => SORT_DESC]]);
255
        $table->define_baseurl('/');
256
 
257
        ob_start();
258
        $table->out(5, false);
259
        $text = ob_get_clean();
260
 
261
        // Student 2 then Student 0 then Student 1.
262
        $student0pos = strpos($text, '<input id="user'.$this->students[0]->id.'" ');
263
        $student1pos = strpos($text, '<input id="user'.$this->students[1]->id.'" ');
264
        $student2pos = strpos($text, '<input id="user'.$this->students[2]->id.'" ');
265
        $this->assertGreaterThan($student2pos, $student0pos, 'Student 2 > Student 0');
266
        $this->assertGreaterThan($student0pos, $student1pos, 'Student 0 > Student 1');
267
    }
268
}