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
namespace core_courseformat\external;
18
 
19
defined('MOODLE_INTERNAL') || die();
20
 
21
global $CFG;
22
require_once($CFG->dirroot . '/webservice/tests/helpers.php');
23
 
24
use core_external\external_api;
25
 
26
/**
27
 * Tests for the get_state class.
28
 *
29
 * @package    core_course
30
 * @category   test
31
 * @copyright  2021 Sara Arjona (sara@moodle.com)
32
 * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
33
 * @coversDefaultClass \core_courseformat\external\get_state
34
 */
35
class get_state_test extends \externallib_advanced_testcase {
36
 
37
    /** @var array Sections in the testing course. */
38
    private $sections;
39
 
40
    /** @var array Activities in the testing course. */
41
    private $activities;
42
 
43
    /**
44
     * Setup to ensure that fixtures are loaded.
45
     */
46
    public static function setupBeforeClass(): void {
47
        global $CFG;
48
 
49
        require_once($CFG->dirroot . '/course/lib.php');
50
        require_once($CFG->dirroot . '/course/format/tests/fixtures/format_theunittest.php');
51
        require_once($CFG->dirroot . '/course/format/tests/fixtures/format_theunittest_output_course_format_state.php');
52
    }
53
 
54
    /**
55
     * Setup testcase.
56
     */
57
    public function setUp(): void {
58
        $this->resetAfterTest();
59
 
60
        $this->sections = [];
61
        $this->activities = [];
62
    }
63
 
64
    /**
65
     * Test tearDown.
66
     */
67
    public function tearDown(): void {
68
        unset($this->sections);
69
        unset($this->activities);
70
    }
71
 
72
    /**
73
     * Test the behaviour of get_state::execute().
74
     *
75
     * @dataProvider get_state_provider
76
     * @covers ::execute
77
     *
78
     * @param string $role The role of the user that will execute the method.
79
     * @param string $format The course format of the course where the method will be executed.
80
     * @param string|null $expectedexception If this call will raise an exception, this is its name.
81
     */
82
    public function test_get_state(string $role, string $format = 'topics', ?string $expectedexception = null): void {
83
        $this->resetAfterTest();
84
 
85
        // Create a course.
86
        $numsections = 6;
87
        $visiblesections = $numsections + 1; // Include topic 0.
88
        $course = $this->getDataGenerator()->create_course(['numsections' => $numsections, 'format' => $format]);
89
        $hiddensections = [4, 6];
90
        foreach ($hiddensections as $section) {
91
            set_section_visible($course->id, $section, 0);
92
        }
93
 
94
        // Create and enrol user.
95
        $isadmin = ($role == 'admin');
96
        $canedit = $isadmin || ($role == 'editingteacher');
97
        if ($isadmin) {
98
            $this->setAdminUser();
99
        } else {
100
            if (!$canedit) {
101
                // User won't see the hidden sections. Remove them from the total.
102
                $visiblesections = $visiblesections - count($hiddensections);
103
            }
104
            $user = $this->getDataGenerator()->create_user();
105
            if ($role != 'unenroled') {
106
                $this->getDataGenerator()->enrol_user($user->id, $course->id, $role);
107
            }
108
            $this->setUser($user);
109
        }
110
 
111
        // Social course format automatically creates a forum activity.
112
        if (course_get_format($course)->get_format() === 'social') {
113
            $cms = get_fast_modinfo($course)->get_cms();
114
 
115
            // Let's add this assertion just to ensure course format has only one activity.
116
            $this->assertCount(1, $cms);
117
            $activitycm = reset($cms);
118
 
119
            // And that activity is a forum.
120
            $this->assertEquals('forum', $activitycm->modname);
121
 
122
            // Assign the activity cm to the activities array.
123
            $this->activities[$activitycm->id] = $activitycm;
124
        } else {
125
            // Add some activities to the course.
126
            $this->create_activity($course->id, 'page', 1, true, $canedit);
127
            $this->create_activity($course->id, 'forum', 1, true, $canedit);
128
            $this->create_activity($course->id, 'book', 1, false, $canedit);
129
            $this->create_activity($course->id, 'assign', 2, false, $canedit);
130
            $this->create_activity($course->id, 'glossary', 4, true, $canedit);
131
            $this->create_activity($course->id, 'label', 5, false, $canedit);
132
            $this->create_activity($course->id, 'feedback', 5, true, $canedit);
133
        }
134
 
135
        if ($expectedexception) {
136
            $this->expectException($expectedexception);
137
        }
138
 
139
        // Get course state.
140
        $result = get_state::execute($course->id);
141
        $result = external_api::clean_returnvalue(get_state::execute_returns(), $result);
142
        $result = json_decode($result);
143
        if ($format == 'theunittest') {
144
            // These course format's hasn't the renderer file, so a debugging message will be displayed.
145
            $this->assertDebuggingCalled();
146
        }
147
 
148
        // Check course information.
149
        $this->assertEquals($numsections, $result->course->numsections);
150
        $this->assertCount($visiblesections, $result->section);
151
        $this->assertCount(count($this->activities), $result->cm);
152
        $this->assertCount(count($result->course->sectionlist), $result->section);
153
        if ($format == 'theunittest') {
154
            $this->assertTrue(property_exists($result->course, 'newfancyelement'));
155
        } else {
156
            $this->assertFalse(property_exists($result->course, 'newfancyelement'));
157
        }
158
 
159
        // Check sections information.
160
        foreach ($result->section as $section) {
161
            if (in_array($section->number, $hiddensections)) {
162
                $this->assertFalse($section->visible);
163
            } else {
164
                $this->assertTrue($section->visible);
165
            }
166
            // Check section is defined in course->sectionlist.
167
            $this->assertContains($section->id, $result->course->sectionlist);
168
            // Check course modules list for this section is the expected.
169
            if (array_key_exists($section->number, $this->sections)) {
170
                $this->assertEquals($this->sections[$section->number], $section->cmlist);
171
            }
172
        }
173
        // Check course modules information.
174
        foreach ($result->cm as $cm) {
175
            $this->assertEquals($this->activities[$cm->id]->name, $cm->name);
176
            $this->assertEquals((bool) $this->activities[$cm->id]->visible, $cm->visible);
177
        }
178
    }
179
 
180
    /**
181
     * Data provider for test_get_state().
182
     *
183
     * @return array
184
     */
185
    public function get_state_provider(): array {
186
        return [
187
            // ROLES. Testing behaviour depending on the user role calling the method.
188
            'Admin user should work' => [
189
                'role' => 'admin',
190
            ],
191
            'Editing teacher should work' => [
192
                'role' => 'editingteacher',
193
            ],
194
            'Student should work' => [
195
                'role' => 'student',
196
            ],
197
            'Unenroled user should raise an exception' => [
198
                'role' => 'unenroled',
199
                'format' => 'topics',
200
                'expectedexception' => 'moodle_exception',
201
            ],
202
 
203
            // COURSEFORMAT. Test behaviour depending on course formats.
204
            'Single activity format should work (admin)' => [
205
                'role' => 'admin',
206
                'format' => 'singleactivity',
207
            ],
208
            'Social format should work (admin)' => [
209
                'role' => 'admin',
210
                'format' => 'social',
211
            ],
212
            'Weeks format should work (admin)' => [
213
                'role' => 'admin',
214
                'format' => 'weeks',
215
            ],
216
            'The unit tests format should work (admin)' => [
217
                'role' => 'admin',
218
                'format' => 'theunittest',
219
            ],
220
            'Single activity format should work (student)' => [
221
                'role' => 'student',
222
                'format' => 'singleactivity',
223
            ],
224
            'Social format should work (student)' => [
225
                'role' => 'student',
226
                'format' => 'social',
227
            ],
228
            'Weeks format should work (student)' => [
229
                'role' => 'student',
230
                'format' => 'weeks',
231
            ],
232
            'The unit tests format should work (student)' => [
233
                'role' => 'student',
234
                'format' => 'theunittest',
235
            ],
236
            'Single activity format should raise an exception (unenroled)' => [
237
                'role' => 'unenroled',
238
                'format' => 'singleactivity',
239
                'expectedexception' => 'moodle_exception',
240
            ],
241
            'Social format should raise an exception (unenroled)' => [
242
                'role' => 'unenroled',
243
                'format' => 'social',
244
                'expectedexception' => 'moodle_exception',
245
            ],
246
            'Weeks format should raise an exception (unenroled)' => [
247
                'role' => 'unenroled',
248
                'format' => 'weeks',
249
                'expectedexception' => 'moodle_exception',
250
            ],
251
            'The unit tests format should raise an exception (unenroled)' => [
252
                'role' => 'unenroled',
253
                'format' => 'theunittest',
254
                'expectedexception' => 'moodle_exception',
255
            ],
256
        ];
257
    }
258
 
259
    /**
260
     * Helper method to create an activity into a section and add it to the $sections and $activities arrays.
261
     * For non-admin users, only visible activities will be added to the activities and sections arrays.
262
     *
263
     * @param int $courseid Course identifier where the activity will be added.
264
     * @param string $type Activity type ('forum', 'assign', ...).
265
     * @param int $section Section number where the activity will be added.
266
     * @param bool $visible Whether the activity will be visible or not.
267
     * @param bool $canedit Whether the activity will be accessed later by a user with editing capabilities
268
     */
269
    private function create_activity(int $courseid, string $type, int $section, bool $visible = true, bool $canedit = true): void {
270
        $activity = $this->getDataGenerator()->create_module(
271
            $type,
272
            ['course' => $courseid],
273
            ['section' => $section, 'visible' => $visible]
274
        );
275
 
276
        list(, $activitycm) = get_course_and_cm_from_instance($activity->id, $type);
277
 
278
        if ($visible || $canedit) {
279
            $this->activities[$activitycm->id] = $activitycm;
280
            $this->sections[$section][] = $activitycm->id;
281
        }
282
    }
283
}