diff --git a/classes/driprelease.php b/classes/driprelease.php
new file mode 100644
index 0000000..02a57f4
--- /dev/null
+++ b/classes/driprelease.php
@@ -0,0 +1,391 @@
+.
+
+namespace tool_driprelease;
+use core_availability\tree;
+/**
+ * Class driprelease
+ *
+ * @package tool_driprelease
+ * @copyright 2024 YOUR NAME Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable
- Generated by php-code-coverage 9.2.31 using PHP 8.2.19 and PHPUnit 9.6.18 at Sun Aug 11 8:46:25 AWST 2024.
+ Generated by php-code-coverage 9.2.31 using PHP 8.2.19 and PHPUnit 9.6.18 at Thu Oct 24 19:13:44 AWST 2024.
Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable
- Generated by php-code-coverage 9.2.31 using PHP 8.2.19 and PHPUnit 9.6.18 at Sun Aug 11 8:46:25 AWST 2024.
+ Generated by php-code-coverage 9.2.31 using PHP 8.2.19 and PHPUnit 9.6.18 at Thu Oct 24 19:13:44 AWST 2024.
Insufficient Coverage
+ tool_driprelease\driprelease 0% tool_driprelease\event\driprelease_updated 0% tool_driprelease\event\driprelease_viewed 0%
@@ -77,6 +78,7 @@ tool_driprelease\privacy\provider 0% Project Risks
+
@@ -114,6 +116,17 @@ tool_driprelease\driprelease 2162 Insufficient Coverage
+
+ update 0%
+ get_table_data 0%
+ update_availability 0%
+ row_fill 0%
+ get_course_module_types 0%
+ add_header 0%
+ get_availability 0%
+ calculate_availability 0%
+ get_sequence 0%
+ manage_selections 0% get_modules 0% init 0% get_description 0%
@@ -135,6 +148,15 @@ init 0% Project Risks
+
+ update_availability 156
+ get_table_data 42
+ get_availability 42
+ manage_selections 42
+ get_sequence 20
+ get_modules 20
+ update 6
+ row_fill 6
@@ -144,7 +166,7 @@ get_course_module_types 6 Project Risks
@@ -163,7 +185,7 @@ Project Risks
.yAxis.tickFormat(d3.format('d'));
d3.select('#classCoverageDistribution svg')
- .datum(getCoverageDistributionData([3,0,0,0,0,0,0,0,0,0,0,0], "Class Coverage"))
+ .datum(getCoverageDistributionData([4,0,0,0,0,0,0,0,0,0,0,0], "Class Coverage"))
.transition().duration(500).call(chart);
nv.utils.windowResize(chart.update);
@@ -181,7 +203,7 @@ Project Risks
.yAxis.tickFormat(d3.format('d'));
d3.select('#methodCoverageDistribution svg')
- .datum(getCoverageDistributionData([5,0,0,0,0,0,0,0,0,0,0,0], "Method Coverage"))
+ .datum(getCoverageDistributionData([16,0,0,0,0,0,0,0,0,0,0,0], "Method Coverage"))
.transition().duration(500).call(chart);
nv.utils.windowResize(chart.update);
@@ -231,7 +253,7 @@ Project Risks
chart.yAxis.axisLabel('Cyclomatic Complexity');
d3.select('#classComplexity svg')
- .datum(getComplexityData([[0,2,"tool_driprelease\\event\\driprelease_updated<\/a>"],[0,2,"tool_driprelease\\event\\driprelease_viewed<\/a>"],[0,1,"tool_driprelease\\privacy\\provider<\/a>"]], 'Class Complexity'))
+ .datum(getComplexityData([[0,46,"tool_driprelease\\driprelease<\/a>"],[0,2,"tool_driprelease\\event\\driprelease_updated<\/a>"],[0,2,"tool_driprelease\\event\\driprelease_viewed<\/a>"],[0,1,"tool_driprelease\\privacy\\provider<\/a>"]], 'Class Complexity'))
.transition()
.duration(500)
.call(chart);
@@ -255,7 +277,7 @@ Project Risks
chart.yAxis.axisLabel('Method Complexity');
d3.select('#methodComplexity svg')
- .datum(getComplexityData([[0,1,"tool_driprelease\\event\\driprelease_updated::init<\/a>"],[0,1,"tool_driprelease\\event\\driprelease_updated::get_description<\/a>"],[0,1,"tool_driprelease\\event\\driprelease_viewed::init<\/a>"],[0,1,"tool_driprelease\\event\\driprelease_viewed::get_description<\/a>"],[0,1,"tool_driprelease\\privacy\\provider::get_reason<\/a>"]], 'Method Complexity'))
+ .datum(getComplexityData([[0,2,"tool_driprelease\\driprelease::update<\/a>"],[0,6,"tool_driprelease\\driprelease::get_table_data<\/a>"],[0,12,"tool_driprelease\\driprelease::update_availability<\/a>"],[0,2,"tool_driprelease\\driprelease::row_fill<\/a>"],[0,2,"tool_driprelease\\driprelease::get_course_module_types<\/a>"],[0,1,"tool_driprelease\\driprelease::add_header<\/a>"],[0,6,"tool_driprelease\\driprelease::get_availability<\/a>"],[0,1,"tool_driprelease\\driprelease::calculate_availability<\/a>"],[0,4,"tool_driprelease\\driprelease::get_sequence<\/a>"],[0,6,"tool_driprelease\\driprelease::manage_selections<\/a>"],[0,4,"tool_driprelease\\driprelease::get_modules<\/a>"],[0,1,"tool_driprelease\\event\\driprelease_updated::init<\/a>"],[0,1,"tool_driprelease\\event\\driprelease_updated::get_description<\/a>"],[0,1,"tool_driprelease\\event\\driprelease_viewed::init<\/a>"],[0,1,"tool_driprelease\\event\\driprelease_viewed::get_description<\/a>"],[0,1,"tool_driprelease\\privacy\\provider::get_reason<\/a>"]], 'Method Complexity'))
.transition()
.duration(500)
.call(chart);
diff --git a/tests/coverage-html/classes/driprelease.php.html b/tests/coverage-html/classes/driprelease.php.html
new file mode 100644
index 0000000..b0c52a9
--- /dev/null
+++ b/tests/coverage-html/classes/driprelease.php.html
@@ -0,0 +1,756 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Total
+
+
+
+
+
+
+ CRAP
+
+
+
+
+
+
+ driprelease
+
+
+
+
+
+
+ 2162
+
+
+
+
+
+
+ update
+
+
+
+
+
+
+ 6
+
+
+
+
+ get_table_data
+
+
+
+
+
+
+ 42
+
+
+
+
+ update_availability
+
+
+
+
+
+
+ 156
+
+
+
+
+ row_fill
+
+
+
+
+
+
+ 6
+
+
+
+
+ get_course_module_types
+
+
+
+
+
+
+ 6
+
+
+
+
+ add_header
+
+
+
+
+
+
+ 2
+
+
+
+
+ get_availability
+
+
+
+
+
+
+ 42
+
+
+
+
+ calculate_availability
+
+
+
+
+
+
+ 2
+
+
+
+
+ get_sequence
+
+
+
+
+
+
+ 20
+
+
+
+
+ manage_selections
+
+
+
+
+
+
+ 42
+
+
+
+
+
+
+ get_modules
+
+
+
+
+
+
+ 20
+
+
+
+
+
+
+
+
+ 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 tool_driprelease;
+ 18 use core_availability\tree;
+ 19 /**
+ 20 * Class driprelease
+ 21 *
+ 22 * @package tool_driprelease
+ 23 * @copyright 2024 YOUR NAME <your@email.com>
+ 24 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ 25 */
+ 26 class driprelease {
+ 27 /**
+ 28 * Adds/updates an instance of driprelease and its related
+ 29 *
+ 30 * @param \stdClass $fromform
+ 31 * @param int $courseid
+ 32 * @return array
+ 33 */
+ 34 public function update(\stdClass $fromform , int $courseid): array {
+ 35 global $DB;
+ 36 $lib = new lib();
+ 37 $dripreleaseid = $DB->get_field('tool_driprelease', 'id', ['courseid' => $courseid]);
+ 38
+ 39 if ($dripreleaseid) {
+ 40 $driprelease = (object) [
+ 41 'id' => $dripreleaseid,
+ 42 'modtype' => $fromform->modtype,
+ 43 'courseid' => $courseid,
+ 44 'activitiespersession' => $fromform->activitiespersession,
+ 45 'sessionlength' => $fromform->sessiongroup['sessionlength'] ?? $fromform->sessionlength,
+ 46 'schedulestart' => $fromform->schedulestart,
+ 47 'schedulefinish' => $fromform->schedulefinish,
+ 48 'coursegroup' => $fromform->coursegroup,
+ 49 'stayavailable' => $fromform->stayavailable,
+ 50 'hideunselected' => $fromform->hideunselected,
+ 51 'resetunselected' => $fromform->resetunselected,
+ 52 'displaydisabled' => $fromform->displaydisabled,
+ 53 ];
+ 54 $DB->update_record('tool_driprelease', $driprelease);
+ 55 $lib->manage_selections($fromform, $dripreleaseid);
+ 56 } else {
+ 57 $driprelease = (object) [
+ 58 'courseid' => $courseid,
+ 59 'modtype' => $fromform->modtype,
+ 60 'activitiespersession' => $fromform->activitiespersession,
+ 61 'sessionlength' => $fromform->sessionlength,
+ 62 'schedulestart' => $fromform->schedulestart,
+ 63 'schedulefinish' => $fromform->schedulefinish,
+ 64 'coursegroup' => $fromform->coursegroup,
+ 65 'stayavailable' => $fromform->stayavailable,
+ 66 'hideunselected' => $fromform->hideunselected,
+ 67 'resetunselected' => $fromform->resetunselected,
+ 68 'displaydisabled' => $fromform->displaydisabled,
+ 69 ];
+ 70 $dripreleaseid = $DB->insert_record('tool_driprelease', $driprelease);
+ 71 $driprelease->id = $dripreleaseid;
+ 72 }
+ 73 $this->manage_selections($fromform, $dripreleaseid);
+ 74 $selections = $DB->get_records_menu('tool_driprelease_cmids', ['driprelease' => $dripreleaseid], null, 'id,coursemoduleid');
+ 75 return [$selections, $driprelease];
+ 76 }
+ 77 /**
+ 78 * Get the rows to be displayed in the schedule of dripped out modules
+ 79 *
+ 80 * @param \stdClass $driprelease
+ 81 * @return array
+ 82 */
+ 83 public function get_table_data(\stdClass $dripdata): array {
+ 84 global $DB;
+ 85 $modules = $this->get_modules($dripdata);
+ 86 $contentcounter = 0;
+ 87 $sessioncounter = 0;
+ 88 $selections = [];
+ 89 if (isset($driprelease->id)) {
+ 90 $selections = $DB->get_records_menu('tool_driprelease_cmids', ['driprelease' => $driprelease->id],
+ 91 null, 'id,coursemoduleid');
+ 92 }
+ 93 foreach ($modules as $cm) {
+ 94 $row['selected'] = in_array($cm->id, $selections) ? 'checked' : "";
+ 95
+ 96 if ($contentcounter % ($dripdata->activitiespersession) == 0) {
+ 97 if ($row['selected'] > "") {
+ 98 $row['calculatedavailability'] = $this->calculate_availability($dripdata, $sessioncounter);
+ 99 $sessioncounter++;
+ 100 }
+ 101 $data[] = $this->add_header($row);
+ 102 }
+ 103 $contentcounter++;
+ 104 $row['modtype'] = $dripdata->modtype;
+ 105 $data[] = $this->row_fill($row, $cm);
+ 106 }
+ 107 return $data ?? [];
+ 108 }
+ 109 /**
+ 110 * Write the availability back to the course_modules table
+ 111 * See https://moodledev.io/docs/apis/subsystems/availability/
+ 112 * @param array $tabledata
+ 113 * @param \stdClass $driprelease
+ 114 * @return void
+ 115 */
+ 116 public function update_availability(array $tabledata, \stdClass $dripdata) {
+ 117 global $DB, $COURSE;
+ 118 $updatecount = 0;
+ 119 foreach ($tabledata as $module) {
+ 120 if (!$module['isheader']) {
+ 121 if (!$module['selected'] == "checked") {
+ 122 $cm = $module['cm'];
+ 123 if ($dripdata->hideunselected) {
+ 124 set_coursemodule_visible($cm->id, false, false);
+ 125 \core\event\course_module_updated::create_from_cm($cm)->trigger();
+ 126 } else {
+ 127 set_coursemodule_visible($cm->id, true, true);
+ 128 }
+ 129 xdebug_break();
+ 130
+ 131 if ($dripdata->resetunselected) {
+ 132 $DB->set_field(
+ 133 'course_modules',
+ 134 'availability',
+ 135 '',
+ 136 ['id' => $module['cm']->id]
+ 137 );
+ 138 }
+ 139 continue;
+ 140 }
+ 141 if (!array_key_exists('calculatedavailability', $module)) {
+ 142 continue;
+ 143 }
+ 144 // Don't write any availability restrictions after the end of the schedule.
+ 145 if ($module['calculatedavailability']['start'] > $dripdata->schedulefinish) {
+ 146 continue;
+ 147 }
+ 148 $cm = $module['cm'];
+ 149 set_coursemodule_visible($cm->id, true, true);
+ 150 \core\event\course_module_updated::create_from_cm($cm)->trigger();
+ 151
+ 152 $availability = $module['calculatedavailability'];
+ 153 $restrictions = [];
+ 154 if ($dripdata->coursegroup) {
+ 155 $restrictions[] = \availability_group\condition::get_json($driprelease->coursegroup);
+ 156 }
+ 157 $restrictions[] = \availability_date\condition::get_json(">=", $availability['start']);
+ 158 if (!$dripdata->stayavailable) {
+ 159 $restrictions[] = \availability_date\condition::get_json("<", $availability['end']);
+ 160 }
+ 161 $showvalue = false;
+ 162 if ($dripdata->displaydisabled) {
+ 163 $showvalue = true;
+ 164 }
+ 165
+ 166 $showc = array_fill(0, count($restrictions), $showvalue);
+ 167 $restrictionsclass = tree::get_root_json($restrictions, tree::OP_AND, $showc);
+ 168
+ 169 $DB->set_field(
+ 170 'course_modules',
+ 171 'availability',
+ 172 json_encode($restrictionsclass),
+ 173 ['id' => $module['cm']->id]
+ 174 );
+ 175 $updatecount++;
+ 176 }
+ 177 }
+ 178 $modulenameplural = get_string('modulenameplural', $dripdata->modtype);
+ 179 $msg = get_string('updated', 'moodle', $updatecount). " ".$modulenameplural;
+ 180 $refresh = optional_param('refresh', 0, PARAM_RAW);
+ 181 if (! $refresh) {
+ 182 \core\notification::add($msg, \core\notification::SUCCESS);
+ 183 rebuild_course_cache($COURSE->id);
+ 184 }
+ 185 }
+ 186 /**
+ 187 * Simplify get_table_data
+ 188 *
+ 189 * @param array $row
+ 190 * @param \cm_info $cm
+ 191 * @return array
+ 192 */
+ 193 private function row_fill(array $row, \cm_info $cm): array {
+ 194 global $DB;
+ 195
+ 196 $details = $DB->get_record($row['modtype'], ['id' => $cm->instance]);
+ 197 $row['cm'] = $cm;
+ 198 $row['intro'] = strip_tags($details->intro);
+ 199 if ($cm->modname == 'quiz') {
+ 200 $questions = $DB->get_records('quiz_slots', ['quizid' => $cm->instance]);
+ 201 $row['questioncount'] = count($questions);
+ 202 }
+ 203 $row['isheader'] = false;
+ 204 $row['id'] = $cm->id;
+ 205 $row['name'] = $cm->name;
+ 206 $row['moduleavailability'] = $this->get_availability($cm->availability);
+ 207 return $row;
+ 208 }
+ 209 /**
+ 210 * Get names of modules on course for showing
+ 211 * in the select element on the form.
+ 212 *
+ 213 * @param int $courseid
+ 214 * @return array
+ 215 */
+ 216 public static function get_course_module_types(int $courseid): array {
+ 217 $modinfo = get_fast_modinfo($courseid);
+ 218 $modtypes = [];
+ 219 foreach ($modinfo->cms as $cm) {
+ 220 $modtypes[$cm->modname] = get_string('pluginname', $cm->modname);
+ 221 }
+ 222 return $modtypes;
+ 223 }
+ 224 /**
+ 225 * Add another session header row in the display/preview of scheduled modules
+ 226 *
+ 227 * @param array $row
+ 228 * @return array
+ 229 */
+ 230 private function add_header(array $row): array {
+ 231 $header = $row;
+ 232 $header['isheader'] = true;
+ 233 $header['cm'] = (object) ['id' => -1];
+ 234 $header['name'] = 'Session';
+ 235 return $header;
+ 236 }
+ 237 /**
+ 238 * Take an optional JSON string as input and return an array containing
+ 239 * the date-related availability information.
+ 240 * *
+ 241 * If the input JSON is empty, the function returns an empty array.
+ 242 *
+ 243 * Loop through each restriction in the JSON object and checks
+ 244 * if the restriction type is "date". If true, it extracts the operator and
+ 245 * timestamp from the restriction object.
+ 246 *
+ 247 * Based on the operator, the function updates the availability array with
+ 248 * the formatted date string using userdate() function.
+ 249 *
+ 250 * The function returns the availability array containing the 'from' and 'to'
+ 251 * dates in a human-readable format.
+ 252 * @param string $json The optional JSON input string containing the availability restrictions
+ 253 * @return array The availability array containing the 'from' and 'to' dates
+ 254 */
+ 255 public function get_availability(?string $json): array {
+ 256 $availability = [];
+ 257 if (empty($json)) {
+ 258 return $availability;
+ 259 }
+ 260 $decoded = json_decode($json);
+ 261 foreach ($decoded->c as $restriction) {
+ 262 if (property_exists($restriction, 'type') && $restriction->type == "date") {
+ 263 $operator = $restriction->d;
+ 264 if ($operator == ">=") {
+ 265 $datetime = $restriction->t;
+ 266 $availability['from'] = userdate($datetime, '%a %d %b %Y %H:%M');
+ 267 } else {
+ 268 $datetime = $restriction->t;
+ 269 $availability['to'] = userdate($datetime, '%a %d %b %Y %H:%M');
+ 270 }
+ 271 }
+ 272 }
+ 273 return $availability;
+ 274 }
+ 275
+ 276 /**
+ 277 * Calculate the dripping out of availability and format the dates for the session labels
+ 278 *
+ 279 * @param \stdClass $driprelease
+ 280 * @param int $sessioncounter
+ 281 * @return array
+ 282 */
+ 283 public function calculate_availability(\stdClass $driprelease, int $sessioncounter): array {
+ 284 $row = [];
+ 285 $daysrepeat = $sessioncounter * $driprelease->sessionlength;
+ 286 $daysoffset = " + $daysrepeat day";
+ 287 $start = strtotime(' + ' . $daysrepeat . ' day', $driprelease->schedulestart);
+ 288 $daysoffset = " + " . (($daysrepeat - 1) + $driprelease->sessionlength) . " day ";
+ 289 $end = strtotime($daysoffset, $driprelease->schedulestart);
+ 290
+ 291 $midnight = strtotime('today midnight', $driprelease->schedulefinish);
+ 292 $endminutes = $driprelease->schedulefinish - $midnight;
+ 293 $end = strtotime('today midnight', $end );
+ 294 $end += $endminutes;
+ 295
+ 296 $row['sessioncounter'] = $sessioncounter + 1;
+ 297 $row['start'] = $start;
+ 298 $row['end'] = $end;
+ 299 return $row;
+ 300 }
+ 301 /**
+ 302 * This is designed to return the coursemods in the order they are displayed on the course
+ 303 * It is currently not used and may be deleted at some point, or the need for it may be obscured
+ 304 * by the way test data means course activities are always in the order they were created.
+ 305 *
+ 306 * @param \stdClass $data
+ 307 * @return array
+ 308 */
+ 309 public function get_sequence(\stdClass $data): array {
+ 310 global $DB;
+ 311 $sql = 'SELECT sequence FROM {course_sections} WHERE course = :course AND sequence > "" ORDER BY section';
+ 312 $coursesequence = $DB->get_records_sql($sql, ['course' => $data->course]);
+ 313 $activitiesordered = [];
+ 314 $i = 0;
+ 315 foreach ($coursesequence as $item) {
+ 316 $temp = explode(',', $item->sequence);
+ 317 foreach ($temp as $t) {
+ 318 if (array_key_exists($t, $data->activities)) {
+ 319 $activitiesordered[$i] = $t;
+ 320 $i++;
+ 321 }
+ 322 }
+ 323 }
+ 324 return $activitiesordered;
+ 325 }
+ 326 /**
+ 327 * Process the checkbox selections and upsert the database records
+ 328 *
+ 329 * @param \stdClass $fromform
+ 330 * @param int $dripreleaseid
+ 331 * @return int $insertedcount // For future testing purposes.
+ 332 */
+ 333 public function manage_selections(\stdClass $fromform, int $dripreleaseid): int {
+ 334 global $DB;
+ 335 if (!isset($fromform->activitygroup)) {
+ 336 return 0;
+ 337 }
+ 338 $moduleids = [];
+ 339 foreach ($fromform->activitygroup as $key => $value) {
+ 340 if ($value == 1) {
+ 341 $moduleids[] = explode('_', $key)[1];
+ 342 }
+ 343 }
+ 344 $selections = $DB->get_records_menu('tool_driprelease_cmids', ['driprelease' => $dripreleaseid], null, 'id,coursemoduleid');
+ 345
+ 346 $todelete = array_diff($selections, $moduleids);
+ 347 if ($todelete) {
+ 348 list($insql, $inparams) = $DB->get_in_or_equal($todelete);
+ 349 $DB->delete_records_select("tool_driprelease_cmids", "coursemoduleid $insql", $inparams);
+ 350 }
+ 351 $toinsert = array_diff($moduleids, $selections);
+ 352 $insertedcount = 0;
+ 353 foreach ($toinsert as $moduleid) {
+ 354 $dataobject = (object) [
+ 355 'driprelease' => $dripreleaseid,
+ 356 'coursemoduleid' => $moduleid,
+ 357 ];
+ 358 $DB->insert_record('tool_driprelease_cmids', $dataobject);
+ 359 $insertedcount ++;
+ 360 }
+ 361 return $insertedcount;
+ 362 }
+ 363 /**
+ 364 * Get course modules given an instance of driprelease
+ 365 *
+ 366 * @param \stdClass $driprelease
+ 367 * @return array
+ 368 */
+ 369 public static function get_modules(\stdClass $dripdata): array {
+ 370 global $DB;
+ 371 $course = $DB->get_record('course', ['id' => $dripdata->courseid]);
+ 372 $modinfo = get_fast_modinfo($course);
+ 373 if (!$modinfo->instances || (!array_key_exists($dripdata->modtype, $modinfo->instances))) {
+ 374 return [];
+ 375 };
+ 376 $modules = [];
+ 377 foreach ($modinfo->instances[$dripdata->modtype] as $cm) {
+ 378 $modules[$cm->id] = $cm;
+ 379 }
+ 380 return $modules;
+ 381 }
+ 382
+
+
+383 } Project Risks
diff --git a/tests/coverage-html/classes/event/driprelease_updated.php.html b/tests/coverage-html/classes/event/driprelease_updated.php.html
index 487f468..7a156f7 100644
--- a/tests/coverage-html/classes/event/driprelease_updated.php.html
+++ b/tests/coverage-html/classes/event/driprelease_updated.php.html
@@ -214,7 +214,7 @@
Legend
Legend
Legend
High: 90% to 100%
- Generated by php-code-coverage 9.2.31 using PHP 8.2.19 and PHPUnit 9.6.18 at Sun Aug 11 8:46:25 AWST 2024. + Generated by php-code-coverage 9.2.31 using PHP 8.2.19 and PHPUnit 9.6.18 at Thu Oct 24 19:13:44 AWST 2024.
diff --git a/tests/coverage-html/classes/index.html b/tests/coverage-html/classes/index.html index 7b5a9e2..8c78ef7 100644 --- a/tests/coverage-html/classes/index.html +++ b/tests/coverage-html/classes/index.html @@ -51,7 +51,7 @@- Generated by php-code-coverage 9.2.31 using PHP 8.2.19 and PHPUnit 9.6.18 at Sun Aug 11 8:46:25 AWST 2024. + Generated by php-code-coverage 9.2.31 using PHP 8.2.19 and PHPUnit 9.6.18 at Thu Oct 24 19:13:44 AWST 2024.
diff --git a/tests/coverage-html/classes/lib.php.html b/tests/coverage-html/classes/lib.php.html new file mode 100644 index 0000000..f6461ea --- /dev/null +++ b/tests/coverage-html/classes/lib.php.html @@ -0,0 +1,131 @@ + + + + ++ | Code Coverage |
+ |||||||||
+ | Lines |
+ Functions and Methods |
+ Classes and Traits |
+ |||||||
Total | ++ | n/a |
+ 0 / 0 |
+ + | n/a |
+ 0 / 0 |
+ CRAP | ++ | n/a |
+ 0 / 0 |
+
lib | ++ | n/a |
+ 0 / 0 |
+ + | n/a |
+ 0 / 0 |
+ 0 | ++ | n/a |
+ 0 / 0 |
+
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 tool_driprelease; |
18 | |
19 | /** |
20 | * Class lib |
21 | * |
22 | * @package tool_driprelease |
23 | * @copyright 2024 YOUR NAME <your@email.com> |
24 | * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later |
25 | */ |
26 | class lib { |
27 | |
28 | |
29 | |
30 | } |
- Generated by php-code-coverage 9.2.31 using PHP 8.2.19 and PHPUnit 9.6.18 at Sun Aug 11 8:46:25 AWST 2024. + Generated by php-code-coverage 9.2.31 using PHP 8.2.19 and PHPUnit 9.6.18 at Thu Oct 24 19:13:44 AWST 2024.
diff --git a/tests/coverage-html/classes/privacy/provider.php.html b/tests/coverage-html/classes/privacy/provider.php.html index 7d4cffe..364b65b 100644 --- a/tests/coverage-html/classes/privacy/provider.php.html +++ b/tests/coverage-html/classes/privacy/provider.php.html @@ -182,7 +182,7 @@Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable
- Generated by php-code-coverage 9.2.31 using PHP 8.2.19 and PHPUnit 9.6.18 at Sun Aug 11 8:46:25 AWST 2024. + Generated by php-code-coverage 9.2.31 using PHP 8.2.19 and PHPUnit 9.6.18 at Thu Oct 24 19:13:44 AWST 2024.
diff --git a/tests/coverage-html/dashboard.html b/tests/coverage-html/dashboard.html index d2f013c..cfadfb0 100644 --- a/tests/coverage-html/dashboard.html +++ b/tests/coverage-html/dashboard.html @@ -57,6 +57,7 @@Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable
- Generated by php-code-coverage 9.2.31 using PHP 8.2.19 and PHPUnit 9.6.18 at Sun Aug 11 8:46:25 AWST 2024. + Generated by php-code-coverage 9.2.31 using PHP 8.2.19 and PHPUnit 9.6.18 at Thu Oct 24 19:13:44 AWST 2024.
diff --git a/tests/coverage-html/index.html b/tests/coverage-html/index.html index a20daef..279e978 100644 --- a/tests/coverage-html/index.html +++ b/tests/coverage-html/index.html @@ -44,21 +44,21 @@- Generated by php-code-coverage 9.2.31 using PHP 8.2.19 and PHPUnit 9.6.18 at Sun Aug 11 8:46:25 AWST 2024. + Generated by php-code-coverage 9.2.31 using PHP 8.2.19 and PHPUnit 9.6.18 at Thu Oct 24 19:13:44 AWST 2024.
diff --git a/tests/coverage-html/lib.php.html b/tests/coverage-html/lib.php.html index 2d18e43..a203534 100644 --- a/tests/coverage-html/lib.php.html +++ b/tests/coverage-html/lib.php.html @@ -42,31 +42,7 @@Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable
- Generated by php-code-coverage 9.2.31 using PHP 8.2.19 and PHPUnit 9.6.18 at Sun Aug 11 8:46:25 AWST 2024. + Generated by php-code-coverage 9.2.31 using PHP 8.2.19 and PHPUnit 9.6.18 at Thu Oct 24 19:13:44 AWST 2024.
diff --git a/tests/coverage-html/view.php.html b/tests/coverage-html/view.php.html index 509e73a..06bf2b3 100644 --- a/tests/coverage-html/view.php.html +++ b/tests/coverage-html/view.php.html @@ -50,7 +50,7 @@Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable
- Generated by php-code-coverage 9.2.31 using PHP 8.2.19 and PHPUnit 9.6.18 at Sun Aug 11 8:46:25 AWST 2024. + Generated by php-code-coverage 9.2.31 using PHP 8.2.19 and PHPUnit 9.6.18 at Thu Oct 24 19:13:44 AWST 2024.
diff --git a/tests/driprelease_test.php b/tests/driprelease_test.php index 522427b..f1f122b 100644 --- a/tests/driprelease_test.php +++ b/tests/driprelease_test.php @@ -32,15 +32,25 @@ global $CFG; require_once($CFG->dirroot . '/mod/quiz/locallib.php'); -/** + +/*** * Unit test for the driprelease functionality. * * @package tool_driprelease * @category test - * @copyright 2023 Marcus Green + * @copyright 2024 Marcus Green * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ +use tool_driprelease; +/** + * Test the code mainly in the tool_driprelease class + */ final class driprelease_test extends \advanced_testcase { + /** + * Instance containing most of the code + * @var driprelease + */ + public $driprelease; /** * Test course @@ -57,11 +67,10 @@ final class driprelease_test extends \advanced_testcase { public $modules; /** - * instance of driprelease - * + * data to be processed * @var \stdClass */ - public $driprelease; + public $dripdata; /** * data from form submission @@ -72,6 +81,7 @@ final class driprelease_test extends \advanced_testcase { public function setUp(): void { global $CFG, $DB; + $this->driprelease = new driprelease(); // Create course with availability enabled. $CFG->enableavailability = true; $generator = $this->getDataGenerator(); @@ -80,17 +90,17 @@ public function setUp(): void { $quizgenerator = $generator->get_plugin_generator('mod_quiz'); - $this->modules[] = $quizgenerator->create_instance(array('course' => $course->id, + $this->modules[] = $quizgenerator->create_instance(['course' => $course->id, 'grademethod' => QUIZ_GRADEHIGHEST, 'grade' => 100.0, 'sumgrades' => 10.0, - 'attempts' => 10)); + 'attempts' => 10]); - $this->modules[] = $quizgenerator->create_instance(array('course' => $course->id, + $this->modules[] = $quizgenerator->create_instance(['course' => $course->id, 'grademethod' => QUIZ_GRADEHIGHEST, 'grade' => 100.0, 'sumgrades' => 10.0, - 'attempts' => 10)); + 'attempts' => 10]); - $this->modules[] = $quizgenerator->create_instance(array('course' => $course->id, + $this->modules[] = $quizgenerator->create_instance(['course' => $course->id, 'grademethod' => QUIZ_GRADEHIGHEST, 'grade' => 100.0, 'sumgrades' => 10.0, - 'attempts' => 10)); + 'attempts' => 10]); foreach ($this->modules as $module) { $activitygroup['activity_'.$module->cmid] = 1; @@ -110,15 +120,15 @@ public function setUp(): void { 'displaydisabled' => 0, ]; - list($selections, $driprelease) = driprelease_update($this->fromform , $this->course1->id); + list($selections, $this->dripdata) = $this->driprelease->update($this->fromform , $this->course1->id); $this->assertCount(3, $selections); - $this->driprelease = $DB->get_record('tool_driprelease', ['id' => $driprelease->id]); + $this->dripdata = $DB->get_record('tool_driprelease', ['id' => $this->dripdata->id]); } /** * Confirm course_modules table has been * written to * - * @covers ::update_availability() + * @covers \tool_driprelease\driprelease::update_availability() */ public function test_update_availability(): void { $this->resetAfterTest(); @@ -126,13 +136,14 @@ public function test_update_availability(): void { $coursemodules = $DB->get_records('course_modules'); $cm = reset($coursemodules); $this->assertEquals($cm->availability, ''); - $tabledata = get_table_data($this->driprelease); + $tabledata = $this->driprelease->get_table_data($this->dripdata); // Element 0 is a header row. $tabledata[1]['selected'] = 1; - update_availability($tabledata, $this->driprelease); + + $this->driprelease->update_availability($tabledata, $this->dripdata); $coursemodules = $DB->get_records('course_modules'); $cm = reset($coursemodules); - $startdate = $this->driprelease->schedulestart; + $startdate = $this->dripdata->schedulestart; // Sessions set to one day in setUp. $this->assertStringContainsString($startdate, $cm->availability); @@ -140,15 +151,41 @@ public function test_update_availability(): void { } /** - * Confirm modules/quizzes in a course are returned - * as expected + * If reset unselected is checked then the availability data + * for the module will be blanked out * + * @covers \tool_driprelease\driprelease::process_unselected * - * @covers ::get_modules() + * @return void + */ + public function test_process_unselected(): void { + $this->resetAfterTest(); + global $DB; + $modules = $this->driprelease->get_table_data($this->dripdata); + $module = $modules[1]; // A non header. + $DB->set_field( + 'course_modules', + 'availability', + 'XXX', + ['id' => $module['cm']->id] + ); + $before = $DB->get_record('course_modules', ['id' => $module['cm']->id]); + $this->assertEquals($before->availability, 'XXX'); + $this->dripdata->resetunselected = 1; + $this->driprelease->process_unselected($module, $this->dripdata); + $after = $DB->get_record('course_modules', ['id' => $module['cm']->id]); + $this->assertEquals($after->availability, ''); + + } + + /** + * Confirm modules/quizzes in a course are returned + * as expected + * @covers \tool_driprelease\driprelease::get_modules */ public function test_get_course_modules(): void { $this->resetAfterTest(); - $modules = get_modules($this->driprelease); + $modules = $this->driprelease->get_modules($this->dripdata); $modulecount = count($modules); $this->assertEquals(count($this->modules), $modulecount); } @@ -158,21 +195,21 @@ public function test_get_course_modules(): void { * as expected * * - * @covers ::get_course_module_types() + * @covers \tool_driprelease\driprelease::get_course_module_types() */ public function test_get_course_module_types(): void { $this->resetAfterTest(); - $moduletypes = get_course_module_types($this->course1->id); + $moduletypes = $this->driprelease->get_course_module_types($this->course1->id); $this->assertArrayHasKey('quiz', $moduletypes); } /** * Get the data that will be output by the mustache table * - * @covers ::get_table_data() + * @covers \tool_driprelease\driprelease::get_table_data() */ public function test_get_table_data(): void { $this->resetAfterTest(); - $tabledata = get_table_data($this->driprelease); + $tabledata = $this->driprelease->get_table_data($this->dripdata); // First row is header row. $header = $tabledata[0]; $this->assertEquals($header['isheader'], true); @@ -196,7 +233,7 @@ public function test_get_table_data(): void { * Check that update doesn't fall over and * selections are set as expected * - * @covers ::driprelease_update() + * @covers \tool_driprelease\driprelease::update() */ public function test_update_instance(): void { $this->resetAfterTest(); @@ -206,9 +243,9 @@ public function test_update_instance(): void { $activitygroup['activity_'.$module->id] = 1; } $this->fromform->activitygroup = $activitygroup; - list($selections, $driprelease) = driprelease_update($this->fromform , $this->course1->id); + list($selections, $this->dripdata) = $this->driprelease->update($this->fromform , $this->course1->id); $this->assertCount(3, $selections); - $this->assertEquals($driprelease->id, $this->driprelease->id); + $this->assertEquals($this->dripdata->id, $this->dripdata->id); } /** @@ -216,7 +253,7 @@ public function test_update_instance(): void { * when when they have been selected in * the form. * - * @covers ::manage_selections() + * @covers \tool_driprelease\driprelease::manage_selections() */ public function test_manage_selections(): void { $this->resetAfterTest(); @@ -225,7 +262,7 @@ public function test_manage_selections(): void { // Three records created by setUp. $this->assertCount(3, $cmids); $this->fromform->activitygroup['activity_101'] = 1; - manage_selections($this->fromform, $this->driprelease->id); + $this->driprelease->manage_selections($this->fromform, $this->dripdata->id); $cmids = $DB->get_records('tool_driprelease_cmids'); // Four after manage_selections was called. $this->assertCount(4, $cmids); @@ -237,11 +274,11 @@ public function test_manage_selections(): void { * and end of a activity session, * e.g. a weeks worth of quizzes. * - * @covers ::add_header() + * @covers \tool_driprelease\driprelease::add_header() */ public function test_add_header(): void { $this->resetAfterTest(); - $header = add_header([]); + $header = $this->driprelease->add_header([]); $this->assertEquals(true, $header['isheader']); $this->assertEquals('Session', $header['name']); $this->assertEquals(-1, $header['cm']->id); @@ -251,17 +288,17 @@ public function test_add_header(): void { * Check get_modules returns items * configured in setUp function * - * @covers ::get_modules() + * @covers \tool_driprelease\driprelease::get_modules() */ public function test_get_modules(): void { $this->resetAfterTest(); - $cmids = get_modules($this->driprelease); + $cmids = $this->driprelease->get_modules($this->dripdata); $this->assertCount(3, $cmids); } /** * Test get_availability with date restrictions - * @covers ::get_availability() + * @covers \tool_driprelease\driprelease::get_availability() */ public function test_get_availability_with_dates(): void { $this->resetAfterTest(); @@ -278,7 +315,7 @@ public function test_get_availability_with_dates(): void { 'to' => 'Mon 1 Feb 2021 00:00', ]; - $availability = get_availability($json); + $availability = $this->driprelease->get_availability($json); // Assert the output. $this->assertSame($expectedoutput, $availability); @@ -286,13 +323,13 @@ public function test_get_availability_with_dates(): void { /** * Test get_availability with no date restrictions - * @covers ::get_availability() + * @covers \tool_driprelease\driprelease::get_availability() */ public function test_get_availability_with_no_dates(): void { $this->resetAfterTest(); $json = ""; - $availability = get_availability($json); + $availability = $this->driprelease->get_availability($json); // Assert the output. $this->assertSame([], $availability); @@ -300,12 +337,12 @@ public function test_get_availability_with_no_dates(): void { /** * Test get_availability with null json - * @covers ::get_availability() + * @covers \tool_driprelease\driprelease::get_availability() */ public function test_get_availability_with_null(): void { $this->resetAfterTest(); - $availability = get_availability(null); + $availability = $this->driprelease->get_availability(null); // Assert the output. $this->assertSame([], $availability); diff --git a/view.php b/view.php index fb760cd..6c68b17 100644 --- a/view.php +++ b/view.php @@ -27,6 +27,8 @@ use tool_driprelease\event\driprelease_updated; use tool_driprelease\event\driprelease_viewed; +use tool_driprelease\driprelease; +$driprelease = new driprelease(); // Course module id. $courseid = optional_param('courseid', 0, PARAM_INT); @@ -59,26 +61,30 @@ $PAGE->set_course($course); global $DB, $USER; -$driprelease = $DB->get_record('tool_driprelease' , ['courseid' => $courseid], '*', IGNORE_MISSING); -if (!$driprelease) { +$dripdata = $DB->get_record('tool_driprelease' , ['courseid' => $courseid], '*', IGNORE_MISSING); +if (!$dripdata) { $config = get_config('tool_driprelease'); - $driprelease = (object)[ + $dripdata = (object)[ 'courseid' => $courseid, 'modtype' => $modtype, 'activitiespersession' => $config->activitiespersession ?? 0, 'schedulestart' => time(), 'coursegroup' => '', 'sessionlength' => $config->sessionlength ?? 0, + 'mydtype' => '', ]; } else { - $driprelease->modtype = $modtype; + $dripdata->modtype = $modtype; } -if (!$driprelease) { - $driprelease = (object) ['courseid' => $courseid]; +if (!$dripdata) { + $dripdata = (object) [ + 'courseid' => $courseid, + 'modtype' => '', + ]; } -$mform = new tool_driprelease_form(null, ['driprelease' => $driprelease]); +$mform = new tool_driprelease_form(null, ['driprelease' => $dripdata]); navigation_node::override_active_url(new moodle_url('admin/tool/driprelease/view.php', ['courseid' => $courseid])); $eventdata = [ @@ -92,20 +98,20 @@ if ($fromform = $mform->get_data()) { if (isset($fromform->submitbutton) || isset($fromform->submitbutton2) || isset($fromform->refresh)) { - $driprelease->schedulestart = $fromform->schedulestart; - $driprelease->stayavailable = $fromform->stayavailable; - $driprelease->hideunselected = $fromform->hideunselected; - $driprelease->coursegroup = $fromform->coursegroup; - $driprelease->moduletype = $fromform->modtype; - $driprelease->refresh = true; - list($selections, $driprelease) = driprelease_update($fromform, $courseid); + $dripdata->schedulestart = $fromform->schedulestart; + $dripdata->stayavailable = $fromform->stayavailable; + $dripdata->hideunselected = $fromform->hideunselected; + $dripdata->coursegroup = $fromform->coursegroup; + $dripdata->moduletype = $fromform->modtype; + $dripdata->refresh = true; + list($selections, $dripdata) = $driprelease->update($fromform, $courseid); if (count($selections) == 0 && !isset($fromform->refresh)) { $msg = get_string('noselections', 'tool_driprelease'); \core\notification::add($msg, \core\notification::WARNING); } - $tabledata = get_table_data($driprelease); - update_availability($tabledata, $driprelease); + $tabledata = $driprelease->get_table_data($dripdata); + $driprelease->update_availability($tabledata, $dripdata); $event = driprelease_updated::create($eventdata); $event->trigger(); @@ -115,7 +121,7 @@ } } -$tabledata = get_table_data($driprelease); +$tabledata = $driprelease->get_table_data($dripdata); $templates = []; $iterator = new DirectoryIterator(__DIR__ . '/templates'); @@ -134,7 +140,7 @@ $out = $OUTPUT->render_from_template('tool_driprelease/'.$templatefile, ['tabledata' => $tabledata, 'modtype' => get_string("pluginname", $modtype)]); -$mform->set_data($driprelease); +$mform->set_data($dripdata); $event = driprelease_viewed::create($eventdata); $event->trigger();