From beb1f62f13a8563bea323e29d7e1a11f293bacce Mon Sep 17 00:00:00 2001 From: Peter Mayer Date: Thu, 1 Oct 2026 10:10:36 +0200 Subject: [PATCH 1/3] MBS-11235: Accept only learningmap course modules in web services --- classes/external/get_dependingmodules.php | 2 +- classes/external/get_learningmap.php | 2 +- tests/external/external_test.php | 70 +++++++++++++++++++++++ 3 files changed, 72 insertions(+), 2 deletions(-) create mode 100644 tests/external/external_test.php diff --git a/classes/external/get_dependingmodules.php b/classes/external/get_dependingmodules.php index 4ec0d282..060e9288 100644 --- a/classes/external/get_dependingmodules.php +++ b/classes/external/get_dependingmodules.php @@ -89,7 +89,7 @@ public static function execute_returns(): external_single_structure { public static function execute(int $cmid): array { $params = self::validate_parameters(self::execute_parameters(), ['cmId' => $cmid]); $cmid = $params['cmId']; - [$course, $cminfo] = get_course_and_cm_from_cmid($cmid); + [$course, $cminfo] = get_course_and_cm_from_cmid($cmid, 'learningmap'); $context = context_module::instance($cmid); self::validate_context($context); require_capability('mod/learningmap:view', $context); diff --git a/classes/external/get_learningmap.php b/classes/external/get_learningmap.php index 68caf943..be0b81d1 100644 --- a/classes/external/get_learningmap.php +++ b/classes/external/get_learningmap.php @@ -90,7 +90,7 @@ public static function execute(int $cmid): array { global $PAGE, $OUTPUT; $params = self::validate_parameters(self::execute_parameters(), ['cmId' => $cmid]); $cmid = $params['cmId']; - [$course, $cminfo] = get_course_and_cm_from_cmid($cmid); + [$course, $cminfo] = get_course_and_cm_from_cmid($cmid, 'learningmap'); $context = context_module::instance($cmid); // Don't render learningmap if not available and user has no override capability. if (!$cminfo->available && !has_capability('moodle/course:ignoreavailabilityrestrictions', $context)) { diff --git a/tests/external/external_test.php b/tests/external/external_test.php new file mode 100644 index 00000000..4256fce3 --- /dev/null +++ b/tests/external/external_test.php @@ -0,0 +1,70 @@ +. + +namespace mod_learningmap\external; + +/** + * Tests for the web service functions of mod_learningmap. + * + * @package mod_learningmap + * @copyright 2026 ISB Bayern + * @author Dr. Peter Mayer + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ +final class external_test extends \advanced_testcase { + #[\PHPUnit\Framework\Attributes\Group('baseline')] + #[\PHPUnit\Framework\Attributes\RunInSeparateProcess] + /** + * The web services only accept course modules of type learningmap. + * + * @covers \mod_learningmap\external\get_learningmap::execute + * @covers \mod_learningmap\external\get_dependingmodules::execute + * @runInSeparateProcess + */ + public function test_execute_rejects_other_module_types(): void { + global $CFG, $DB; + $this->resetAfterTest(); + $generator = $this->getDataGenerator(); + $course = $generator->create_course(); + $student = $generator->create_and_enrol($course, 'student'); + $page = $generator->create_module('page', ['course' => $course->id]); + // The own map needs no places, its rendering is not under test. + $placestore = json_decode(file_get_contents($CFG->dirroot . '/mod/learningmap/tests/generator/test.json'), true); + $placestore = array_merge($placestore, ['places' => [], 'paths' => [], 'startingplaces' => [], 'targetplaces' => []]); + $ownmap = $generator->create_module('learningmap', ['course' => $course->id, 'placestore' => json_encode($placestore)]); + + // A map in a foreign course whose instance id equals the id of the page. + $othercourse = $generator->create_course(); + $othermap = $generator->create_module('learningmap', ['course' => $othercourse->id]); + $DB->set_field('learningmap', 'id', $page->id, ['id' => $othermap->id]); + $DB->set_field('course_modules', 'instance', $page->id, ['id' => $othermap->cmid]); + rebuild_course_cache($othercourse->id, true); + + $this->setUser($student); + $functions = [get_learningmap::class, get_dependingmodules::class]; + foreach ($functions as $function) { + try { + $function::execute($page->cmid); + $this->fail('Expected moodle_exception for ' . $function); + } catch (\moodle_exception $e) { + $this->assertSame('invalidcoursemoduleid', $e->errorcode); + } + } + + $this->assertNotEmpty(get_learningmap::execute($ownmap->cmid)['content']); + $this->assertIsArray(get_dependingmodules::execute($ownmap->cmid)); + } +} From 11e121c9001bef8bc584ddb164d2d9083e35eadf Mon Sep 17 00:00:00 2001 From: "thomas.schoenlein" Date: Tue, 13 Oct 2026 08:25:11 +0200 Subject: [PATCH 2/3] MBS-11235: Codestyle fixes - to squash --- tests/external/external_test.php | 1 - tests/mod_learningmap_helper_test.php | 1 + 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/external/external_test.php b/tests/external/external_test.php index 4256fce3..6a439e12 100644 --- a/tests/external/external_test.php +++ b/tests/external/external_test.php @@ -25,7 +25,6 @@ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ final class external_test extends \advanced_testcase { - #[\PHPUnit\Framework\Attributes\Group('baseline')] #[\PHPUnit\Framework\Attributes\RunInSeparateProcess] /** * The web services only accept course modules of type learningmap. diff --git a/tests/mod_learningmap_helper_test.php b/tests/mod_learningmap_helper_test.php index bb7108fc..913f021b 100644 --- a/tests/mod_learningmap_helper_test.php +++ b/tests/mod_learningmap_helper_test.php @@ -23,6 +23,7 @@ * @category test * @copyright 2025 ISB Bayern * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + * @covers \mod_learningmap\helper */ #[\PHPUnit\Framework\Attributes\CoversClass(helper::class)] #[\PHPUnit\Framework\Attributes\CoversMethod(helper::class, 'repair_learningmap_record')] From 91be739b2685076b4c2140ef1e0765b1353cb689 Mon Sep 17 00:00:00 2001 From: "thomas.schoenlein" Date: Tue, 13 Oct 2026 08:34:39 +0200 Subject: [PATCH 3/3] MBS-11235: Codestyle fixes II - to squash --- tests/mod_learningmap_helper_test.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/mod_learningmap_helper_test.php b/tests/mod_learningmap_helper_test.php index 913f021b..703b8830 100644 --- a/tests/mod_learningmap_helper_test.php +++ b/tests/mod_learningmap_helper_test.php @@ -16,6 +16,9 @@ namespace mod_learningmap; +#[\PHPUnit\Framework\Attributes\CoversClass(helper::class)] +#[\PHPUnit\Framework\Attributes\CoversMethod(helper::class, 'repair_learningmap_record')] +#[\PHPUnit\Framework\Attributes\CoversMethod(helper::class, 'render_activity_header_for_modal')] /** * Tests for Learning map helper class * @@ -25,9 +28,6 @@ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later * @covers \mod_learningmap\helper */ -#[\PHPUnit\Framework\Attributes\CoversClass(helper::class)] -#[\PHPUnit\Framework\Attributes\CoversMethod(helper::class, 'repair_learningmap_record')] -#[\PHPUnit\Framework\Attributes\CoversMethod(helper::class, 'render_activity_header_for_modal')] final class mod_learningmap_helper_test extends \advanced_testcase { /** * Tests the repair_learningmap_record method.