PlayerGroup

Student self-service group formation activity for Moodle — full documentation.

English | Português

View on GitHub Download .zip

🧪 Automated Tests

PlayerGroup ships with a PHPUnit test suite covering business logic, web services, reports and exports, the renderer and mobile app output, the public API, and Privacy API compliance, plus a Behat suite for browser acceptance. Every CI push runs against the full matrix (Moodle 4.5 → 5.x, PostgreSQL & MariaDB).

Core (tests/, tests/backup/, tests/completion/, tests/local/, tests/privacy/)

Test file Cases What is covered
lib_test.php 9 add_instance/delete_instance lifecycle, supported-features declaration; deleting an activity pointed at a pre-existing grouping only removes groups this instance registered, leaving a foreign group and the grouping itself untouched; an auto-created (“new” mode) grouping is still removed once left empty
playergroup_grade_test.php 4 Grade award on join, bulk award, grade persistence after leaving, no grade when disabled
completion/custom_completion_test.php 2 Custom completion rule completionjoingroup: incomplete without a group, complete once the student belongs to a group registered for the activity
backup/restore_test.php 3 Backup/restore round-trip for content-only and user-data modes; original course unaffected
local/group_lock_test.php 3 Lock acquired when free; throws grouplockbusy when the resource is held by a genuinely different database connection (not just a second lock-factory instance on the same one); a different activity instance’s lock is never blocked by another
local/member_list_test.php 4 The leader is placed first regardless of their position in the input; non-leaders are sorted alphabetically; a list with no leader still sorts everyone alphabetically; an empty list returns an empty array
privacy/provider_test.php 11 Metadata declaration, context discovery, data export (creator/receiver), bulk and targeted deletion
Subtotal 36  

Web Services (tests/external/)

Test file Cases What is covered
create_group_test.php 12 All privacy levels, password hashing, creator membership, capability enforcement, duplicate and invalid-cmid guards, completion tracking, throws and cleans up (no orphaned native group) when the joining member add fails, blocked while another request holds the per-instance lock
join_group_test.php 11 Success, completion tracking, already-in-group and closed-group rejections, protected-group joins (correct password; wrong password rejected with a plain moodle_exception, never coding_exception), invited user joining via password, resolution of pending invites on join, throws instead of silently succeeding when the joining member add fails, blocked while another request holds the per-instance lock
leave_group_test.php 8 Success, canleave guard, not-in-group guard, empty-group auto-deletion, leadership transfer, pending invite cancellation
edit_group_test.php 6 Updates name/description/badge; a non-creator is rejected; a new password is hashed; leaving the password blank keeps the existing hash; switching away from protected clears it; a groupid from another activity instance is rejected
accept_invite_test.php 7 Success, completion tracking (manual/automatic), wrong-user and already-handled rejections, throws instead of silently succeeding when the joining member add fails, blocked while another request holds the per-instance lock
reject_invite_test.php 4 Success, wrong-user rejection, already-handled rejection, invalid inviteid
send_invite_test.php 3 Pending invite creation, re-inviting a student after they join and leave a group, a sender without moodle/course:viewparticipants is rejected
get_activity_data_test.php 2 The mobile/web payload includes each group’s member list and leader flag, validated against execute_returns() — this is what the mobile app actually consumes; members are ordered leader-first, then alphabetically
Subtotal 53  

Reports & Exports (tests/controller/)

Test file Cases What is covered
export_test.php 2 CSV export contains a localized row per logged event; an activity with no events exports only the header row
export_groups_test.php 3 One row per member with the correct group, privacy, and role (leader/member) labels; a closed group is labelled correctly; an activity with no groups exports only the header row
Subtotal 5  

Output & Mobile App (tests/output/)

Test file Cases What is covered
renderer_test.php 10 Student view empty/populated states; the group card’s data-groupname attribute uses the formatted (escaped) name, never the raw one; activity log report empty/populated states; groups-and-members report empty/populated states; the join/create/edit group password fields all set autocomplete="new-password" so the browser never offers to fill in the student’s own saved site password
mobile_test.php 4 mobile_init returns init.js verbatim; mobile_course_view returns the rendered page plus group/member data; capability enforcement; the rendered page binds the group card’s description to the sanitised field, never the raw one
Subtotal 14  

Public API (tests/api/)

Test file Cases What is covered
group_info_test.php 6 No group returns null; a group’s summary fields; default badge fallback; bulk badge lookup across several groups; empty input; a native group with no PlayerGroup metadata is omitted
Subtotal 6  
Grand Total 114  
vendor/bin/phpunit --testsuite mod_playergroup

Line coverage by class (PHPUnit + Xdebug):

Class Line coverage
api\group_info 100%
controller\export 100%
output\mobile 100%
output\renderer 100%
local\group_lock 100%
local\member_list 100%
controller\export_groups 98%
privacy\provider 94%
instance_manager 93%
external\edit_group 92%
external\leave_group 92%
external\create_group 90%
external\join_group 91%
external\send_invite 89%
external\accept_invite 89%
external\get_activity_data 89%
external\reject_invite 88%
completion\custom_completion 56%
Overall 80%

The event/*.php classes aren’t listed — Moodle only loads them lazily when the corresponding event actually fires, so the instrumentation never sees them.

Behat — Acceptance Tests

Feature file Scenarios What is covered
create_group.feature 2 Student creates an open group; creation blocked after already joining one
join_group.feature 2 Second student joins and sees the My Group badge; one-group-per-student enforcement
join_protected_group.feature 3 Pressing enter in the password field joins the group, exactly like clicking Save (native form submission no longer drops the page’s id parameter and crashes); the wrong password shows a dialog on the activity page itself, never a system error page; the password field carries autocomplete="new-password"
view.feature 3 Student sees the empty state and Create Group button; report link visibility by role
invite_colleagues.feature 1 A group creator sees an enrolled colleague listed in the invite modal
view_members.feature 1 A student opens the member list and sees both members, with the leader marked
Total 12  
php admin/tool/behat/cli/init.php
vendor/bin/behat --tags=@mod_playergroup --profile=chrome