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 |
* Unit tests for the coursecompleted condition.
|
|
|
19 |
*
|
|
|
20 |
* @package availability_coursecompleted
|
|
|
21 |
* @copyright 2017 iplusacademy (www.iplusacademy.org)
|
|
|
22 |
* @author Renaat Debleu <info@eWallah.net>
|
|
|
23 |
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
|
|
24 |
*/
|
|
|
25 |
|
|
|
26 |
namespace availability_coursecompleted;
|
|
|
27 |
|
|
|
28 |
|
|
|
29 |
use availability_coursecompleted\{condition, frontend};
|
|
|
30 |
use completion_info;
|
|
|
31 |
use core_availability\{tree, info_module, capability_checker};
|
|
|
32 |
use core_completion;
|
|
|
33 |
|
|
|
34 |
/**
|
|
|
35 |
* Unit tests for the coursecompleted condition.
|
|
|
36 |
*
|
|
|
37 |
* @package availability_coursecompleted
|
|
|
38 |
* @copyright 2017 iplusacademy (www.iplusacademy.org)
|
|
|
39 |
* @author Renaat Debleu <info@eWallah.net>
|
|
|
40 |
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
|
|
41 |
* @coversDefaultClass \availability_coursecompleted
|
|
|
42 |
*/
|
|
|
43 |
final class advanced_test extends \advanced_testcase {
|
|
|
44 |
/** @var stdClass course. */
|
|
|
45 |
private $course;
|
|
|
46 |
|
|
|
47 |
/** @var stdClass cm. */
|
|
|
48 |
private $cm;
|
|
|
49 |
|
|
|
50 |
/** @var int userid. */
|
|
|
51 |
private $userid;
|
|
|
52 |
|
|
|
53 |
/** @var int compid. */
|
|
|
54 |
private $compid;
|
|
|
55 |
|
|
|
56 |
/** @var int teacherid. */
|
|
|
57 |
private $teacherid;
|
|
|
58 |
|
|
|
59 |
/**
|
|
|
60 |
* Create course and page.
|
|
|
61 |
*/
|
|
|
62 |
public function setUp(): void {
|
|
|
63 |
global $CFG, $DB;
|
|
|
64 |
require_once($CFG->dirroot . '/completion/criteria/completion_criteria.php');
|
|
|
65 |
require_once($CFG->dirroot . '/completion/criteria/completion_criteria_activity.php');
|
|
|
66 |
require_once($CFG->dirroot . '/availability/tests/fixtures/mock_info.php');
|
|
|
67 |
require_once($CFG->dirroot . '/availability/tests/fixtures/mock_info_module.php');
|
|
|
68 |
require_once($CFG->libdir . '/completionlib.php');
|
|
|
69 |
$this->resetAfterTest();
|
|
|
70 |
$this->setAdminUser();
|
|
|
71 |
$CFG->enablecompletion = true;
|
|
|
72 |
$CFG->enableavailability = true;
|
|
|
73 |
set_config('enableavailability', true);
|
|
|
74 |
$dg = $this->getDataGenerator();
|
|
|
75 |
$this->course = $dg->create_course(['enablecompletion' => 1]);
|
|
|
76 |
$this->userid = $dg->create_user()->id;
|
|
|
77 |
$this->compid = $dg->create_user()->id;
|
|
|
78 |
$this->teacherid = $dg->create_user()->id;
|
|
|
79 |
$role = $DB->get_field('role', 'id', ['shortname' => 'student']);
|
|
|
80 |
$dg->enrol_user($this->userid, $this->course->id, $role);
|
|
|
81 |
$dg->enrol_user($this->compid, $this->course->id, $role);
|
|
|
82 |
$role = $DB->get_field('role', 'id', ['shortname' => 'editingteacher']);
|
|
|
83 |
$dg->enrol_user($this->teacherid, $this->course->id, $role);
|
|
|
84 |
$feedback = $dg->get_plugin_generator('mod_feedback')->create_instance(['course' => $this->course]);
|
|
|
85 |
$this->cm = get_fast_modinfo($this->course)->get_cm($feedback->cmid);
|
|
|
86 |
$ccompletion = new \completion_completion(['course' => $this->course->id, 'userid' => $this->compid]);
|
|
|
87 |
$ccompletion->mark_complete();
|
|
|
88 |
rebuild_course_cache($this->course->id, true);
|
|
|
89 |
}
|
|
|
90 |
|
|
|
91 |
/**
|
|
|
92 |
* Tests constructing and using coursecompleted condition as part of tree.
|
|
|
93 |
* @covers \availability_coursecompleted\condition
|
|
|
94 |
*/
|
|
|
95 |
public function test_tree(): void {
|
|
|
96 |
$info1 = new \core_availability\mock_info($this->course, $this->userid);
|
|
|
97 |
$info2 = new \core_availability\mock_info($this->course, $this->compid);
|
|
|
98 |
|
|
|
99 |
$structure1 = (object)['op' => '|', 'show' => true, 'c' => [(object)['type' => 'coursecompleted', 'id' => '1']]];
|
|
|
100 |
$structure2 = (object)['op' => '|', 'show' => true, 'c' => [(object)['type' => 'coursecompleted', 'id' => '0']]];
|
|
|
101 |
$tree1 = new tree($structure1);
|
|
|
102 |
$tree2 = new tree($structure2);
|
|
|
103 |
|
|
|
104 |
$this->setuser($this->compid);
|
|
|
105 |
$this->assertTrue($tree1->check_available(false, $info2, true, $this->compid)->is_available());
|
|
|
106 |
$this->assertFalse($tree2->check_available(false, $info2, true, $this->compid)->is_available());
|
|
|
107 |
|
|
|
108 |
$this->setuser($this->userid);
|
|
|
109 |
$this->assertFalse($tree1->check_available(false, $info1, true, $this->userid)->is_available());
|
|
|
110 |
$this->assertTrue($tree2->check_available(false, $info1, true, $this->userid)->is_available());
|
|
|
111 |
}
|
|
|
112 |
|
|
|
113 |
/**
|
|
|
114 |
* Tests the get_description and get_standalone_description functions.
|
|
|
115 |
* @covers \availability_coursecompleted\condition
|
|
|
116 |
* @covers \availability_coursecompleted\frontend
|
|
|
117 |
*/
|
|
|
118 |
public function test_get_description(): void {
|
|
|
119 |
$nau = 'Not available unless: ';
|
|
|
120 |
$sections = get_fast_modinfo($this->course)->get_section_info_all();
|
|
|
121 |
|
|
|
122 |
$frontend = new frontend();
|
|
|
123 |
$name = 'availability_coursecompleted\frontend';
|
|
|
124 |
$this->assertFalse(\phpunit_util::call_internal_method($frontend, 'allow_add', [$this->course], $name));
|
|
|
125 |
|
|
|
126 |
$data = (object) ['id' => $this->course->id, 'criteria_activity' => [$this->cm->id => 1]];
|
|
|
127 |
$criterion = new \completion_criteria_activity();
|
|
|
128 |
$criterion->update_config($data);
|
|
|
129 |
$this->assertTrue(\phpunit_util::call_internal_method($frontend, 'allow_add', [$this->course], $name));
|
|
|
130 |
$this->assertTrue(\phpunit_util::call_internal_method($frontend, 'allow_add', [$this->course, null, $sections[0]], $name));
|
|
|
131 |
$this->assertTrue(\phpunit_util::call_internal_method($frontend, 'allow_add', [$this->course, null, $sections[1]], $name));
|
|
|
132 |
|
|
|
133 |
$info = new \core_availability\mock_info_module($this->userid, $this->cm);
|
|
|
134 |
$completed = new condition((object)['type' => 'coursecompleted', 'id' => '1']);
|
|
|
135 |
$information = $completed->get_description(true, false, $info);
|
|
|
136 |
$this->assertEquals($information, get_string('getdescription', 'availability_coursecompleted'));
|
|
|
137 |
$information = $completed->get_description(true, true, $info);
|
|
|
138 |
$this->assertEquals($information, get_string('getdescriptionnot', 'availability_coursecompleted'));
|
|
|
139 |
$information = $completed->get_standalone_description(true, false, $info);
|
|
|
140 |
$this->assertEquals($information, $nau . get_string('getdescription', 'availability_coursecompleted'));
|
|
|
141 |
$information = $completed->get_standalone_description(true, true, $info);
|
|
|
142 |
$this->assertEquals($information, $nau . get_string('getdescriptionnot', 'availability_coursecompleted'));
|
|
|
143 |
|
|
|
144 |
$completed = new condition((object)['type' => 'coursecompleted', 'id' => '0']);
|
|
|
145 |
$information = $completed->get_description(true, false, $info);
|
|
|
146 |
$this->assertEquals($information, get_string('getdescriptionnot', 'availability_coursecompleted'));
|
|
|
147 |
$information = $completed->get_description(true, true, $info);
|
|
|
148 |
$this->assertEquals($information, get_string('getdescription', 'availability_coursecompleted'));
|
|
|
149 |
$information = $completed->get_standalone_description(true, false, $info);
|
|
|
150 |
$this->assertEquals($information, $nau . get_string('getdescriptionnot', 'availability_coursecompleted'));
|
|
|
151 |
$information = $completed->get_standalone_description(true, true, $info);
|
|
|
152 |
$this->assertEquals($information, $nau . get_string('getdescription', 'availability_coursecompleted'));
|
|
|
153 |
}
|
|
|
154 |
|
|
|
155 |
/**
|
|
|
156 |
* Tests is aplied to user lists.
|
|
|
157 |
* @covers \availability_coursecompleted\condition
|
|
|
158 |
*/
|
|
|
159 |
public function test_is_applied_to_user_lists(): void {
|
|
|
160 |
$info = new \core_availability\mock_info_module($this->userid, $this->cm);
|
|
|
161 |
$cond = new condition((object)['type' => 'coursecompleted', 'id' => '1']);
|
|
|
162 |
$this->assertTrue($cond->is_applied_to_user_lists());
|
|
|
163 |
|
|
|
164 |
$checker = new \core_availability\capability_checker(\context_course::instance($this->course->id));
|
|
|
165 |
$arr = [
|
|
|
166 |
$this->userid => \core_user::get_user($this->userid),
|
|
|
167 |
$this->compid => \core_user::get_user($this->compid),
|
|
|
168 |
$this->teacherid => \core_user::get_user($this->teacherid), ];
|
|
|
169 |
|
|
|
170 |
$result = $cond->filter_user_list([], true, $info, $checker);
|
|
|
171 |
$this->assertEquals([], $result);
|
|
|
172 |
|
|
|
173 |
$result = $cond->filter_user_list($arr, true, $info, $checker);
|
|
|
174 |
$this->assertArrayHasKey($this->userid, $result);
|
|
|
175 |
$this->assertArrayNotHasKey($this->compid, $result);
|
|
|
176 |
$this->assertArrayHasKey($this->teacherid, $result);
|
|
|
177 |
|
|
|
178 |
$result = $cond->filter_user_list($arr, false, $info, $checker);
|
|
|
179 |
$this->assertArrayHasKey($this->teacherid, $result);
|
|
|
180 |
$this->assertArrayHasKey($this->compid, $result);
|
|
|
181 |
$this->assertArrayNotHasKey($this->userid, $result);
|
|
|
182 |
}
|
|
|
183 |
|
|
|
184 |
/**
|
|
|
185 |
* Tests a page before and after completion.
|
|
|
186 |
* @covers \availability_coursecompleted\condition
|
|
|
187 |
* @covers \availability_coursecompleted\frontend
|
|
|
188 |
*/
|
|
|
189 |
public function test_page(): void {
|
|
|
190 |
$info = new info_module($this->cm);
|
|
|
191 |
$cond = new condition((object)['type' => 'coursecompleted', 'id' => '1']);
|
|
|
192 |
$this->assertFalse($cond->is_available(false, $info, true, $this->userid));
|
|
|
193 |
$this->assertFalse($cond->is_available(false, $info, false, $this->userid));
|
|
|
194 |
$this->assertTrue($cond->is_available(true, $info, false, $this->userid));
|
|
|
195 |
$this->assertTrue($cond->is_available(true, $info, true, $this->userid));
|
|
|
196 |
|
|
|
197 |
$ccompletion = new \completion_completion(['course' => $this->course->id, 'userid' => $this->userid]);
|
|
|
198 |
$ccompletion->mark_complete();
|
|
|
199 |
$this->assertTrue($cond->is_available(false, $info, true, $this->userid));
|
|
|
200 |
$this->assertTrue($cond->is_available(false, $info, false, $this->userid));
|
|
|
201 |
$this->assertFalse($cond->is_available(true, $info, false, $this->userid));
|
|
|
202 |
$this->assertFalse($cond->is_available(true, $info, true, $this->userid));
|
|
|
203 |
|
|
|
204 |
// No id.
|
|
|
205 |
$cond = new condition((object)['type' => 'coursecompleted']);
|
|
|
206 |
$this->assertFalse($cond->is_available(false, $info, false, $this->userid));
|
|
|
207 |
$this->assertFalse($cond->is_available_for_all());
|
|
|
208 |
$this->assertFalse($cond->update_dependency_id(null, 1, 2));
|
|
|
209 |
$this->assertEquals($cond->__toString(), '{coursecompleted:False}');
|
|
|
210 |
$this->assertEquals(
|
|
|
211 |
$cond->get_standalone_description(true, true, $info),
|
|
|
212 |
'Not available unless: You completed this course.'
|
|
|
213 |
);
|
|
|
214 |
}
|
|
|
215 |
}
|