From 200e0bcd7503a8f008f17c788c2dfd0e3c883e47 Mon Sep 17 00:00:00 2001 From: cbadusch Date: Wed, 25 Feb 2026 14:59:12 +0100 Subject: [PATCH 1/5] GL-69 Kontrolle availability_user bei der Auswahl vieler Benutzer Wunderbyte-GmbH/wko-complete#6 --- classes/condition.php | 2 +- tests/behat/availability_user.feature | 92 +++++++++++++++++++ .../moodle-availability_user-form-debug.js | 13 ++- .../moodle-availability_user-form-min.js | 2 +- .../moodle-availability_user-form.js | 13 ++- yui/src/form/js/form.js | 13 ++- 6 files changed, 112 insertions(+), 23 deletions(-) create mode 100644 tests/behat/availability_user.feature diff --git a/classes/condition.php b/classes/condition.php index 1298853..fefa963 100644 --- a/classes/condition.php +++ b/classes/condition.php @@ -41,7 +41,7 @@ class condition extends \core_availability\condition { public function __construct($structure) { $this->userids = []; if (isset($structure->userids)) { - $this->userids = $structure->userids; + $this->userids = (array)$structure->userids; } // Ensure compatibility with old version. if (isset($structure->userid)) { diff --git a/tests/behat/availability_user.feature b/tests/behat/availability_user.feature new file mode 100644 index 0000000..ba35867 --- /dev/null +++ b/tests/behat/availability_user.feature @@ -0,0 +1,92 @@ +@availability @availability_user +Feature: availability_user + In order to control student access to activities + As a teacher + I need to set user conditions which prevent student access + + Background: + Given the following "courses" exist: + | fullname | shortname | format | numsections | + | Course 1 | C1 | topics | 3 | + And the following "users" exist: + | username | firstname | lastname | + | teacher1 | Teacher | One | + | student1 | Alice | Smith | + | student2 | Bob | Jones | + | student3 | Carol | White | + And the following "course enrolments" exist: + | user | course | role | + | teacher1 | C1 | editingteacher | + | student1 | C1 | student | + | student2 | C1 | student | + | student3 | C1 | student | + And the following "activities" exist: + | activity | course | name | + | page | C1 | P1 | + + @javascript + Scenario: Restricting access to a single user works correctly + Given I am on the "P1" "page activity editing" page logged in as "teacher1" + And I expand all fieldsets + And I click on "Add restriction..." "button" + And I click on "#availability_addrestriction_user" "css_element" + And I set the field "availability_user_userids" to "Alice Smith" + And I click on ".availability-item .availability-eye img" "css_element" + And I click on "Save and return to course" "button" + + # student1 (Alice) should see P1, others should not. + When I am on the "Course 1" "course" page logged in as "student1" + Then I should see "P1" in the "region-main" "region" + + When I am on the "Course 1" "course" page logged in as "student2" + Then I should not see "P1" in the "region-main" "region" + + @javascript + Scenario: Selecting all users via Ctrl+A saves all of them correctly + # Regression test: Ctrl+A on the multi-select was broken because the plugin + # listened to 'click' (never fired for keyboard selection) and fillValue used + # a broken YUI chain get('options').get('_nodes') returning array-of-arrays. + Given I am on the "P1" "page activity editing" page logged in as "teacher1" + And I expand all fieldsets + And I click on "Add restriction..." "button" + And I click on "#availability_addrestriction_user" "css_element" + # Click the first option to give the select keyboard focus, then Ctrl+A. + And I click on "Alice Smith" "option" in the "#availability_user_userids" "css_element" + And I press the ctrl a key + And I click on ".availability-item .availability-eye img" "css_element" + And I click on "Save and return to course" "button" + + # All three students must be allowed — none should be excluded. + When I am on the "Course 1" "course" page logged in as "student1" + Then I should see "P1" in the "region-main" "region" + + When I am on the "Course 1" "course" page logged in as "student2" + Then I should see "P1" in the "region-main" "region" + + When I am on the "Course 1" "course" page logged in as "student3" + Then I should see "P1" in the "region-main" "region" + + # Re-open and verify all three names are still selected (save/load round-trip). + When I am on the "P1" "page activity editing" page logged in as "teacher1" + And I expand all fieldsets + Then the field "availability_user_userids" matches value "Bob Jones, Teacher One, Alice Smith, Carol White" + + @javascript + Scenario: Selecting a subset of users saves the correct subset + Given I am on the "P1" "page activity editing" page logged in as "teacher1" + And I expand all fieldsets + And I click on "Add restriction..." "button" + And I click on "#availability_addrestriction_user" "css_element" + And I set the field "availability_user_userids" to "Alice Smith, Bob Jones" + And I click on ".availability-item .availability-eye img" "css_element" + And I click on "Save and return to course" "button" + + # Alice and Bob can see P1; Carol cannot. + When I am on the "Course 1" "course" page logged in as "student1" + Then I should see "P1" in the "region-main" "region" + + When I am on the "Course 1" "course" page logged in as "student2" + Then I should see "P1" in the "region-main" "region" + + When I am on the "Course 1" "course" page logged in as "student3" + Then I should not see "P1" in the "region-main" "region" diff --git a/yui/build/moodle-availability_user-form/moodle-availability_user-form-debug.js b/yui/build/moodle-availability_user-form/moodle-availability_user-form-debug.js index a6ac176..3f040c4 100644 --- a/yui/build/moodle-availability_user-form/moodle-availability_user-form-debug.js +++ b/yui/build/moodle-availability_user-form/moodle-availability_user-form-debug.js @@ -41,7 +41,7 @@ M.availability_user.form.getNode = function(json) { if (!M.availability_user.form.addedEvents) { M.availability_user.form.addedEvents = true; var root = Y.one('#fitem_id_availabilityconditionsjson'); - root.delegate('click', function() { + root.delegate('change', function() { M.core_availability.form.update(); }, '.availability_user select'); } @@ -50,14 +50,13 @@ M.availability_user.form.getNode = function(json) { }; M.availability_user.form.fillValue = function(value, node) { - var userSelect = node.one('#availability_user_userids'); - var options = userSelect.get('options').get('_nodes'); var users = []; - options.forEach(function(o) { - if (o.get('selected')) { - users.push(o.get('value')); + var options = node.getDOMNode().querySelectorAll('select option'); + for (var i = 0; i < options.length; i++) { + if (options[i].selected) { + users.push(options[i].value); } - }); + } value.userids = users; }; diff --git a/yui/build/moodle-availability_user-form/moodle-availability_user-form-min.js b/yui/build/moodle-availability_user-form/moodle-availability_user-form-min.js index 77ff80a..10ec64e 100644 --- a/yui/build/moodle-availability_user-form/moodle-availability_user-form-min.js +++ b/yui/build/moodle-availability_user-form/moodle-availability_user-form-min.js @@ -1 +1 @@ -YUI.add("moodle-availability_user-form",function(t,i){M.availability_user=M.availability_user||{},M.availability_user.form=t.Object(M.core_availability.plugin),M.availability_user.form.initInner=function(i){this.params=i},M.availability_user.form.getNode=function(i){var a,e,l='",a=t.Node.create(""+l+""),e=i.userids||[],i.userid&&e.push(i.userid),e.forEach(function(i){null===a.one("option[value="+i+"]")&&a.one("select").appendChild(t.Node.create('