diff --git a/.upgradenotes/MDL-84809-2025082110281911.yml b/.upgradenotes/MDL-84809-2025082110281911.yml new file mode 100644 index 00000000000..e09e2b2c1c2 --- /dev/null +++ b/.upgradenotes/MDL-84809-2025082110281911.yml @@ -0,0 +1,12 @@ +issueNumber: MDL-84809 +notes: + mod_workshop: + - message: >- + The function `workshop::count_submissions` has been deprecated and + should no longer be used, use `workshop::count_all_submissions` + instead. + type: deprecated + - message: >- + The function `workshop::count_assessments` has been deprecated and + should no longer be used, use `workshop::count_all_assessments` instead. + type: deprecated diff --git a/public/mod/workshop/classes/courseformat/overview.php b/public/mod/workshop/classes/courseformat/overview.php index 97b9f40e4c4..b687c3efcad 100644 --- a/public/mod/workshop/classes/courseformat/overview.php +++ b/public/mod/workshop/classes/courseformat/overview.php @@ -181,8 +181,10 @@ class overview extends \core_courseformat\activityoverviewbase { return null; } - $submissions = $this->workshop->count_submissions(); - $total = $this->workshop->count_participants(); + $groups = array_map(fn($group) => $group->id, $this->get_groups_for_filtering()); + + $submissions = $this->workshop->count_all_submissions(groupids: $groups); + $total = $this->workshop->count_all_participants(groupids: $groups); if (!$total) { return new overviewitem( @@ -213,14 +215,14 @@ class overview extends \core_courseformat\activityoverviewbase { * @return overviewitem|null An overview item, or null if the user lacks the required capability. */ private function get_extra_assessments_overview(): ?overviewitem { - global $USER; - if (!has_capability('mod/workshop:viewallassessments', $this->cm->context)) { return null; } - $assessments = $this->workshop->count_assessments(true); - $total = $this->workshop->count_assessments(false); + $groups = array_map(fn($group) => $group->id, $this->get_groups_for_filtering()); + + $assessments = $this->workshop->count_all_assessments(true, $groups); + $total = $this->workshop->count_all_assessments(false, $groups); if (!$total) { return new overviewitem( diff --git a/public/mod/workshop/locallib.php b/public/mod/workshop/locallib.php index 3c6c83d8591..5d7a22878f0 100644 --- a/public/mod/workshop/locallib.php +++ b/public/mod/workshop/locallib.php @@ -657,6 +657,24 @@ class workshop { return count($this->get_participants($musthavesubmission, $groupid)); } + /** + * Returns the total number of participants in the workshop + * + * This is a convenience method that uses {@see count_enrolled_users()} to count all users + * with the capabilities mod/workshop:submit and mod/workshop:peerassess. + * + * @param array $groupids If not empty, return only participants in the specified groups + * @return int + */ + public function count_all_participants(array $groupids = []): int { + return count_enrolled_users( + context: $this->context, + withcapability: ['mod/workshop:submit', 'mod/workshop:peerassess'], + groupids: $groupids, + onlyactive: true, + ); + } + /** * Checks if the given user is an actively enrolled participant in the workshop * @@ -743,66 +761,151 @@ class workshop { /** * Returns the total number of records that would be returned by {@link self::get_submissions()} * + * @deprecated since Moodle 5.1 + * @todo Remove this method in Moodle 6.0 (MDL-86399). + * * @param mixed $authorid int|array|'all' If set to [array of] integer, return submission[s] of the given user[s] only * @param int $groupid If non-zero, return only submissions by authors in the specified group * @return int number of records */ + #[\core\attribute\deprecated( + replacement: 'count_all_submissions', + since: '5.1', + mdl: 'MDL-84809', + )] public function count_submissions($authorid='all', $groupid=0) { - global $DB; + \core\deprecation::emit_deprecation([self::class, __FUNCTION__]); + + $authorids = []; + $groupids = []; + + if (is_array($authorid)) { + $authorids = $authorid; + } else if ($authorid !== 'all') { + $authorids[] = $authorid; + } - $params = array('workshopid' => $this->id); - $sql = "SELECT COUNT(s.id) - FROM {workshop_submissions} s - JOIN {user} u ON (s.authorid = u.id)"; if ($groupid) { - $sql .= " JOIN {groups_members} gm ON (gm.userid = u.id AND gm.groupid = :groupid)"; - $params['groupid'] = $groupid; - } - $sql .= " WHERE s.example = 0 AND s.workshopid = :workshopid"; - - if ('all' === $authorid) { - // no additional conditions - } elseif (!empty($authorid)) { - list($usql, $uparams) = $DB->get_in_or_equal($authorid, SQL_PARAMS_NAMED); - $sql .= " AND authorid $usql"; - $params = array_merge($params, $uparams); - } else { - // $authorid is empty - return 0; + $groupids[] = $groupid; } - return $DB->count_records_sql($sql, $params); + return $this->count_all_submissions($authorids, $groupids); + } + + /** + * Returns the total number of submissions in the workshop + * + * @param array $authorids If not empty, return only submissions by the given authors + * @param array $groupids If not empty, return only submissions by authors in the specified groups + * @return int Number of submissions + */ + public function count_all_submissions(array $authorids = [], array $groupids = []): int { + $db = \core\di::get(\moodle_database::class); + + $authorwhere = ''; + $authorparams = []; + if ($authorids) { + [$authorsql, $authorparams] = $db->get_in_or_equal($authorids, SQL_PARAMS_NAMED); + $authorwhere = " AND authorid $authorsql"; + } + + $groupjoin = ''; + $groupwhere = ''; + $groupparams = []; + if ($groupids) { + $groupsqljoin = groups_get_members_join($groupids, 'u.id', $this->context); + $groupjoin = $groupsqljoin->joins; + $groupwhere = !empty($groupsqljoin->wheres) ? " AND {$groupsqljoin->wheres}" : ''; + $groupparams = $groupsqljoin->params; + } + + $sql = "SELECT COUNT(ws.id) + FROM {workshop_submissions} ws + JOIN {user} u ON (ws.authorid = u.id) + $groupjoin + WHERE ws.example = 0 AND ws.workshopid = :workshopid + $authorwhere + $groupwhere"; + + return $db->count_records_sql( + $sql, + [ + 'workshopid' => $this->id, + ...$authorparams, + ...$groupparams, + ], + ); + } + + /** + * Returns the total number of assessments in the workshop. + * + * @deprecated since Moodle 5.1 + * @todo Remove this method in Moodle 6.0 (MDL-86399). + * + * @param bool $onlygraded If true, count only graded assessments + * @param int|null $groupid If not null, return only assessments by reviewers in the specified group + * @return int Number of assessments + */ + #[\core\attribute\deprecated( + replacement: 'count_all_assessments', + since: '5.1', + mdl: 'MDL-84809', + )] + public function count_assessments(bool $onlygraded = false, ?int $groupid = null): int { + \core\deprecation::emit_deprecation([self::class, __FUNCTION__]); + + $groupids = []; + + if ($groupid) { + $groupids[] = $groupid; + } + + return $this->count_all_assessments($onlygraded, $groupids); } /** * Returns the total number of assessments in the workshop. * * @param bool $onlygraded If true, count only graded assessments - * @param int|null $groupid If not null, return only assessments by reviewers in the specified group + * @param array $groupids If not empty, return only assessments by reviewers in the specified groups * @return int Number of assessments */ - public function count_assessments(bool $onlygraded = false, ?int $groupid = null): int { - global $DB; + public function count_all_assessments(bool $onlygraded = false, array $groupids = []): int { + $db = \core\di::get(\moodle_database::class); + + $groupjoin = ''; + $groupwhere = ''; + $groupparams = []; + if ($groupids) { + $groupsqljoin = groups_get_members_join($groupids, 'u.id', $this->context); + $groupjoin = $groupsqljoin->joins; + $groupwhere = !empty($groupsqljoin->wheres) ? " AND {$groupsqljoin->wheres}" : ''; + $groupparams = $groupsqljoin->params; + } + + $onlygradedwhere = ''; + if ($onlygraded) { + $onlygradedwhere = " AND s.grade IS NOT NULL"; + } - $params = ['workshopid' => $this->id]; $sql = "SELECT COUNT(s.id) FROM {workshop_assessments} s JOIN {workshop_submissions} ws ON (s.submissionid = ws.id) JOIN {user} u ON (ws.authorid = u.id) - JOIN {workshop} w ON (ws.workshopid = w.id)"; + JOIN {workshop} w ON (ws.workshopid = w.id) + $groupjoin + WHERE w.id = :workshopid + $onlygradedwhere + $groupwhere"; - if ($groupid) { - $sql .= " JOIN {groups_members} gm ON (gm.userid = u.id AND gm.groupid = :groupid)"; - $params['groupid'] = $groupid; - } - - if ($onlygraded) { - $sql .= " WHERE s.grade IS NOT NULL AND w.id = :workshopid"; - } else { - $sql .= " WHERE w.id = :workshopid"; - } - - return $DB->count_records_sql($sql, $params); + return $db->count_records_sql( + $sql, + [ + 'workshopid' => $this->id, + ...$groupparams, + ], + ); } @@ -812,7 +915,7 @@ class workshop { * Fetches data from {workshop_submissions} and adds some useful information from other * tables. Does not return textual fields to prevent possible memory lack issues. * - * @see self::count_submissions() + * @see self::count_all_submissions() * @param mixed $authorid int|array|'all' If set to [array of] integer, return submission[s] of the given user[s] only * @param int $groupid If non-zero, return only submissions by authors in the specified group * @param int $limitfrom Return a subset of records, starting at this point (optional) diff --git a/public/mod/workshop/renderer.php b/public/mod/workshop/renderer.php index 0c33d404cf3..603b1552e8a 100644 --- a/public/mod/workshop/renderer.php +++ b/public/mod/workshop/renderer.php @@ -1388,7 +1388,10 @@ class mod_workshop_renderer extends plugin_renderer_base { $data = $workshop->prepare_grading_report_data($USER->id, $groupid, $page, $perpage, $sortby, $sorthow); if ($data) { $countparticipants = $workshop->count_participants(); - $countsubmissions = $workshop->count_submissions(array_keys($data->grades), $groupid); + $countsubmissions = $workshop->count_all_submissions( + array_keys($data->grades), + $groupid ? [$groupid] : [], + ); $a = new stdClass(); $a->submitted = $countsubmissions; $a->notsubmitted = $data->totalcount - $countsubmissions; diff --git a/public/mod/workshop/tests/courseformat/overview_test.php b/public/mod/workshop/tests/courseformat/overview_test.php index 48ab4a82161..ad4e13dada3 100644 --- a/public/mod/workshop/tests/courseformat/overview_test.php +++ b/public/mod/workshop/tests/courseformat/overview_test.php @@ -26,24 +26,23 @@ use core_courseformat\local\overview\overviewfactory; /** * Tests for Workshop overview integration. * - * @covers \mod_workshop\course\overview * @package mod_workshop * @category test * @copyright 2025 Ferran Recio * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ +#[\PHPUnit\Framework\Attributes\CoversClass(overview::class)] final class overview_test extends \advanced_testcase { /** * Test get_grade_item_names method. * - * @dataProvider data_provider_get_grade_item_names - * @covers ::get_grade_item_names * @param string $user * @param bool $expectempty * @param bool $hassubmission * @param bool $hasassesment */ + #[\PHPUnit\Framework\Attributes\DataProvider('data_provider_get_grade_item_names')] public function test_get_grade_item_names( string $user, bool $expectempty, @@ -169,11 +168,10 @@ final class overview_test extends \advanced_testcase { /** * Test get_extra_phase_overview method. * - * @covers ::get_extra_phase_overview - * @dataProvider data_provider_get_extra_phase_overview * @param string $user * @param int $currentphase */ + #[\PHPUnit\Framework\Attributes\DataProvider('data_provider_get_extra_phase_overview')] public function test_get_extra_phase_overview(string $user, int $currentphase): void { $this->resetAfterTest(); $this->setAdminUser(); @@ -257,14 +255,13 @@ final class overview_test extends \advanced_testcase { /** * Test get_extra_deadline_overview method. * - * @covers ::get_extra_deadline_overview - * @dataProvider data_provider_get_extra_deadline_overview * @param string $user * @param int $currentphase * @param int $submissionend * @param int $assessmentend * @param int|null $expectedincrement null if the item should be null. */ + #[\PHPUnit\Framework\Attributes\DataProvider('data_provider_get_extra_deadline_overview')] public function test_get_extra_deadline_overview( string $user, int $currentphase, @@ -398,31 +395,39 @@ final class overview_test extends \advanced_testcase { /** * Test get_extra_submissions_overview and get_extra_assessments_overview methods. * - * @covers ::get_extra_submissions_overview - * @covers ::get_extra_assessments_overview - * @dataProvider data_provider_get_extra_submissions_overview - * @param string $user + * @param string $role * @param int $currentphase + * @param int $groupmode * @param bool $hasstudentactivity * @param bool $expectnull + * @param array $expected */ + #[\PHPUnit\Framework\Attributes\DataProvider('data_provider_get_extra_submissions_overview')] public function test_get_extra_submissions_overview( - string $user, + string $role, int $currentphase, + int $groupmode, bool $hasstudentactivity, bool $expectnull, + array $expected = [], ): void { $this->resetAfterTest(); $this->setAdminUser(); $course = $this->getDataGenerator()->create_course(); - $teacher = $this->getDataGenerator()->create_and_enrol($course, 'teacher'); - $student = $this->getDataGenerator()->create_and_enrol($course, 'student'); + $student1 = $this->getDataGenerator()->create_and_enrol($course, 'student'); $student2 = $this->getDataGenerator()->create_and_enrol($course, 'student'); + $currentuser = $this->getDataGenerator()->create_and_enrol($course, $role); + + if ($groupmode != NOGROUPS) { + $group1 = $this->getDataGenerator()->create_group(['courseid' => $course->id]); + $this->getDataGenerator()->create_group_member(['userid' => $currentuser->id, 'groupid' => $group1->id]); + $this->getDataGenerator()->create_group_member(['userid' => $student1->id, 'groupid' => $group1->id]); + } $activity = $this->getDataGenerator()->create_module( 'workshop', - ['course' => $course->id], + ['course' => $course->id, 'groupmode' => $groupmode], ); $cm = get_fast_modinfo($course)->get_cm($activity->cmid); @@ -452,28 +457,37 @@ final class overview_test extends \advanced_testcase { if ($hasstudentactivity) { // Create some submissions. - $submissionid = $generator->create_submission( + $student1submissionid = $generator->create_submission( $activity->id, - $student->id, + $student1->id, ['title' => 'My custom title', 'grade' => 85.00000], ); - $generator->create_submission( + $student2submissionid = $generator->create_submission( $activity->id, $student2->id, ['title' => 'My custom title', 'grade' => 65.00000], ); - // Assess one submission. + // Assess some submissions. $generator->create_assessment( - $submissionid, - $student->id, - ['weight' => 3, 'grade' => 95.00000], + $student1submissionid, + $currentuser->id, + ['weight' => 3, 'grade' => 45.00000], + ); + $generator->create_assessment( + $student2submissionid, + $currentuser->id, + ['weight' => 3, 'grade' => 55.00000], + ); + $generator->create_assessment( + $student2submissionid, + $currentuser->id, + ['weight' => 3, 'grade' => 65.00000], ); } $manager = new \workshop($activity, $cm, $course, $cm->context); $manager->switch_phase($currentphase); - $currentuser = ($user == 'teacher') ? $teacher : $student; $this->setUser($currentuser); $overview = overviewfactory::create($cm); @@ -494,12 +508,10 @@ final class overview_test extends \advanced_testcase { } $this->assertEquals(get_string('submissions', 'mod_workshop'), $itemsubmissions->get_name()); - $expected = ($hasstudentactivity) ? 2 : 0; - $this->assertEquals($expected, $itemsubmissions->get_value()); + $this->assertEquals($expected['submissions'], $itemsubmissions->get_value()); $this->assertEquals(get_string('assessments', 'mod_workshop'), $itemassessment->get_name()); - $expected = ($hasstudentactivity) ? 1 : 0; - $this->assertEquals($expected, $itemassessment->get_value()); + $this->assertEquals($expected['assessments'], $itemassessment->get_value()); } /** @@ -510,123 +522,200 @@ final class overview_test extends \advanced_testcase { public static function data_provider_get_extra_submissions_overview(): array { return [ 'teacher setup phase without activity' => [ - 'user' => 'teacher', + 'role' => 'editingteacher', 'currentphase' => \workshop::PHASE_SETUP, + 'groupmode' => NOGROUPS, 'hasstudentactivity' => false, 'expectnull' => false, + 'expected' => ['submissions' => 0, 'assessments' => 0], ], 'student setup phase without activity' => [ - 'user' => 'student', + 'role' => 'student', 'currentphase' => \workshop::PHASE_SETUP, + 'groupmode' => NOGROUPS, 'hasstudentactivity' => false, 'expectnull' => true, ], 'teacher submission phase without activity' => [ - 'user' => 'teacher', + 'role' => 'editingteacher', 'currentphase' => \workshop::PHASE_SUBMISSION, + 'groupmode' => NOGROUPS, 'hasstudentactivity' => false, 'expectnull' => false, + 'expected' => ['submissions' => 0, 'assessments' => 0], ], 'student submission phase without activity' => [ - 'user' => 'student', + 'role' => 'student', 'currentphase' => \workshop::PHASE_SUBMISSION, + 'groupmode' => NOGROUPS, 'hasstudentactivity' => false, 'expectnull' => true, ], 'teacher assessment phase without activity' => [ - 'user' => 'teacher', + 'role' => 'editingteacher', 'currentphase' => \workshop::PHASE_ASSESSMENT, + 'groupmode' => NOGROUPS, 'hasstudentactivity' => false, 'expectnull' => false, + 'expected' => ['submissions' => 0, 'assessments' => 0], ], 'student assessment phase without activity' => [ - 'user' => 'student', + 'role' => 'student', 'currentphase' => \workshop::PHASE_ASSESSMENT, + 'groupmode' => NOGROUPS, 'hasstudentactivity' => false, 'expectnull' => true, ], 'teacher evaluation phase without activity' => [ - 'user' => 'teacher', + 'role' => 'editingteacher', 'currentphase' => \workshop::PHASE_EVALUATION, + 'groupmode' => NOGROUPS, 'hasstudentactivity' => false, 'expectnull' => false, + 'expected' => ['submissions' => 0, 'assessments' => 0], ], 'student evaluation phase without activity' => [ - 'user' => 'student', + 'role' => 'student', 'currentphase' => \workshop::PHASE_EVALUATION, + 'groupmode' => NOGROUPS, 'hasstudentactivity' => false, 'expectnull' => true, ], 'teacher closed phase without activity' => [ - 'user' => 'teacher', + 'role' => 'editingteacher', 'currentphase' => \workshop::PHASE_CLOSED, + 'groupmode' => NOGROUPS, 'hasstudentactivity' => false, 'expectnull' => false, + 'expected' => ['submissions' => 0, 'assessments' => 0], ], 'student closed phase without activity' => [ - 'user' => 'student', + 'role' => 'student', 'currentphase' => \workshop::PHASE_CLOSED, + 'groupmode' => NOGROUPS, 'hasstudentactivity' => false, 'expectnull' => true, ], // Tests with assessments. 'teacher setup phase with activity' => [ - 'user' => 'teacher', + 'role' => 'editingteacher', 'currentphase' => \workshop::PHASE_SETUP, + 'groupmode' => NOGROUPS, 'hasstudentactivity' => true, 'expectnull' => false, + 'expected' => ['submissions' => 2, 'assessments' => 3], ], 'student setup phase with activity' => [ - 'user' => 'student', + 'role' => 'student', 'currentphase' => \workshop::PHASE_SETUP, + 'groupmode' => NOGROUPS, 'hasstudentactivity' => true, 'expectnull' => true, ], 'teacher submission phase with activity' => [ - 'user' => 'teacher', + 'role' => 'editingteacher', 'currentphase' => \workshop::PHASE_SUBMISSION, + 'groupmode' => NOGROUPS, 'hasstudentactivity' => true, 'expectnull' => false, + 'expected' => ['submissions' => 2, 'assessments' => 3], ], 'student submission phase with activity' => [ - 'user' => 'student', + 'role' => 'student', 'currentphase' => \workshop::PHASE_SUBMISSION, + 'groupmode' => NOGROUPS, 'hasstudentactivity' => true, 'expectnull' => true, ], 'teacher assessment phase with activity' => [ - 'user' => 'teacher', + 'role' => 'editingteacher', 'currentphase' => \workshop::PHASE_ASSESSMENT, + 'groupmode' => NOGROUPS, 'hasstudentactivity' => true, 'expectnull' => false, + 'expected' => ['submissions' => 2, 'assessments' => 3], ], 'student assessment phase with activity' => [ - 'user' => 'student', + 'role' => 'student', 'currentphase' => \workshop::PHASE_ASSESSMENT, + 'groupmode' => NOGROUPS, 'hasstudentactivity' => true, 'expectnull' => true, ], 'teacher evaluation phase with activity' => [ - 'user' => 'teacher', + 'role' => 'editingteacher', 'currentphase' => \workshop::PHASE_EVALUATION, + 'groupmode' => NOGROUPS, 'hasstudentactivity' => true, 'expectnull' => false, + 'expected' => ['submissions' => 2, 'assessments' => 3], ], 'student evaluation phase with activity' => [ - 'user' => 'student', + 'role' => 'student', 'currentphase' => \workshop::PHASE_EVALUATION, + 'groupmode' => NOGROUPS, 'hasstudentactivity' => true, 'expectnull' => true, ], 'teacher closed phase with activity' => [ - 'user' => 'teacher', + 'role' => 'editingteacher', 'currentphase' => \workshop::PHASE_CLOSED, + 'groupmode' => NOGROUPS, 'hasstudentactivity' => true, 'expectnull' => false, + 'expected' => ['submissions' => 2, 'assessments' => 3], ], 'student closed phase with activity' => [ - 'user' => 'student', + 'role' => 'student', 'currentphase' => \workshop::PHASE_CLOSED, + 'groupmode' => NOGROUPS, + 'hasstudentactivity' => true, + 'expectnull' => true, + ], + // Group mode tests. + 'teacher closed phase with group activity (separate groups)' => [ + 'role' => 'editingteacher', + 'currentphase' => \workshop::PHASE_CLOSED, + 'groupmode' => SEPARATEGROUPS, + 'hasstudentactivity' => true, + 'expectnull' => false, + 'expected' => ['submissions' => 2, 'assessments' => 3], + ], + 'non-editing teacher closed phase with group activity (separate groups)' => [ + 'role' => 'teacher', + 'currentphase' => \workshop::PHASE_CLOSED, + 'groupmode' => SEPARATEGROUPS, + 'hasstudentactivity' => true, + 'expectnull' => false, + 'expected' => ['submissions' => 1, 'assessments' => 1], + ], + 'student closed phase with group activity (separate groups)' => [ + 'role' => 'student', + 'currentphase' => \workshop::PHASE_CLOSED, + 'groupmode' => SEPARATEGROUPS, + 'hasstudentactivity' => true, + 'expectnull' => true, + ], + 'teacher closed phase with group activity (visible groups)' => [ + 'role' => 'editingteacher', + 'currentphase' => \workshop::PHASE_CLOSED, + 'groupmode' => VISIBLEGROUPS, + 'hasstudentactivity' => true, + 'expectnull' => false, + 'expected' => ['submissions' => 2, 'assessments' => 3], + ], + 'non-editing teacher closed phase with group activity (visible groups)' => [ + 'role' => 'teacher', + 'currentphase' => \workshop::PHASE_CLOSED, + 'groupmode' => VISIBLEGROUPS, + 'hasstudentactivity' => true, + 'expectnull' => false, + 'expected' => ['submissions' => 2, 'assessments' => 3], + ], + 'student closed phase with group activity (visible groups)' => [ + 'role' => 'student', + 'currentphase' => \workshop::PHASE_CLOSED, + 'groupmode' => VISIBLEGROUPS, 'hasstudentactivity' => true, 'expectnull' => true, ], @@ -636,12 +725,10 @@ final class overview_test extends \advanced_testcase { /** * Test get_actions_overview. * - * @covers ::get_actions_overview - * @dataProvider provider_test_get_actions_overview - * * @param string $role * @param array|null $expected */ + #[\PHPUnit\Framework\Attributes\DataProvider('provider_test_get_actions_overview')] public function test_get_actions_overview( string $role, ?array $expected diff --git a/public/mod/workshop/tests/locallib_test.php b/public/mod/workshop/tests/locallib_test.php index ec7f11bc93f..d1dc68a08d7 100644 --- a/public/mod/workshop/tests/locallib_test.php +++ b/public/mod/workshop/tests/locallib_test.php @@ -39,6 +39,7 @@ require_once(__DIR__ . '/fixtures/testable.php'); /** * Test cases for the internal workshop api */ +#[\PHPUnit\Framework\Attributes\CoversClass(workshop::class)] final class locallib_test extends \advanced_testcase { /** @var object */ @@ -778,8 +779,6 @@ final class locallib_test extends \advanced_testcase { /** * Test init_initial_bar function. - * - * @covers \workshop::init_initial_bar */ public function test_init_initial_bar(): void { global $SESSION; @@ -811,8 +810,6 @@ final class locallib_test extends \advanced_testcase { /** * Test empty init_initial_bar - * - * @covers \workshop::init_initial_bar */ public function test_init_initial_bar_empty(): void { $this->resetAfterTest(); @@ -825,8 +822,6 @@ final class locallib_test extends \advanced_testcase { /** * Test get_initial_first function - * - * @covers \workshop::get_initial_first */ public function test_get_initial_first(): void { $this->resetAfterTest(); @@ -840,8 +835,6 @@ final class locallib_test extends \advanced_testcase { /** * Test get_initial_last function - * - * @covers \workshop::get_initial_last */ public function test_get_initial_last(): void { $this->resetAfterTest(); @@ -856,7 +849,6 @@ final class locallib_test extends \advanced_testcase { /** * Get the protected propertyinitialbarprefs from workshop class. * - * @coversNothing * @return array initialbarspref property. eg ['i_first' => 'A', 'i_last' => 'B'] */ private function get_initial_bar_prefs_property(): array { @@ -869,10 +861,7 @@ final class locallib_test extends \advanced_testcase { } /** - * Test count_submissions and count_assessments methods. - * - * @covers \workshop::count_submissions - * @covers \workshop::count_assessments + * Test count_all_submissions and count_all_assessments methods. */ public function test_count_submissions_count_assessments(): void { $this->resetAfterTest(); @@ -945,23 +934,59 @@ final class locallib_test extends \advanced_testcase { $manager = new workshop($activity, $cm, $course, $cm->context); - $this->assertEquals(4, $manager->count_submissions()); - $this->assertEquals(4, $manager->count_submissions('all')); - $this->assertEquals(1, $manager->count_submissions($student1->id)); - $this->assertEquals(1, $manager->count_submissions($student2->id)); + $this->assertEquals(4, $manager->count_all_submissions()); + $this->assertEquals(1, $manager->count_all_submissions(authorids: [$student1->id])); + $this->assertEquals(2, $manager->count_all_submissions(authorids: [$student1->id, $student2->id])); - $this->assertEquals(2, $manager->count_submissions('all', $group1->id)); - $this->assertEquals(1, $manager->count_submissions('all', $group2->id)); - $this->assertEquals(1, $manager->count_submissions($student1->id, $group1->id)); - $this->assertEquals(0, $manager->count_submissions($student2->id, $group1->id)); + $this->assertEquals(2, $manager->count_all_submissions(groupids: [$group1->id])); + $this->assertEquals(1, $manager->count_all_submissions(groupids: [$group2->id])); + $this->assertEquals(3, $manager->count_all_submissions(groupids: [$group1->id, $group2->id])); + $this->assertEquals(1, $manager->count_all_submissions(authorids: [$student1->id], groupids: [$group1->id])); + $this->assertEquals(0, $manager->count_all_submissions(authorids: [$student2->id], groupids: [$group1->id])); - $this->assertEquals(4, $manager->count_assessments()); - $this->assertEquals(2, $manager->count_assessments(true)); + $this->assertEquals(4, $manager->count_all_assessments()); + $this->assertEquals(2, $manager->count_all_assessments(onlygraded: true)); - $this->assertEquals(2, $manager->count_assessments(false, $group1->id)); - $this->assertEquals(1, $manager->count_assessments(true, $group1->id)); + $this->assertEquals(2, $manager->count_all_assessments(onlygraded: false, groupids: [$group1->id])); + $this->assertEquals(1, $manager->count_all_assessments(onlygraded: true, groupids: [$group1->id])); - $this->assertEquals(1, $manager->count_assessments(false, $group2->id)); - $this->assertEquals(0, $manager->count_assessments(true, $group2->id)); + $this->assertEquals(1, $manager->count_all_assessments(onlygraded: false, groupids: [$group2->id])); + $this->assertEquals(0, $manager->count_all_assessments(onlygraded: true, groupids: [$group2->id])); + + $this->assertEquals(3, $manager->count_all_assessments(onlygraded: false, groupids: [$group1->id, $group2->id])); + $this->assertEquals(1, $manager->count_all_assessments(onlygraded: true, groupids: [$group1->id, $group2->id])); + } + + /** + * Test count_all_participants method. + */ + public function test_count_all_participants(): void { + $this->resetAfterTest(); + $this->setAdminUser(); + + $course = $this->getDataGenerator()->create_course(); + $group1 = $this->getDataGenerator()->create_group(['courseid' => $course->id]); + $group2 = $this->getDataGenerator()->create_group(['courseid' => $course->id]); + $student1 = $this->getDataGenerator()->create_and_enrol($course, 'student'); + $student2 = $this->getDataGenerator()->create_and_enrol($course, 'student'); + $student3 = $this->getDataGenerator()->create_and_enrol($course, 'student'); + $student4 = $this->getDataGenerator()->create_and_enrol($course, 'student'); + $guest = $this->getDataGenerator()->create_and_enrol($course, 'guest'); + + $this->getDataGenerator()->create_group_member(['userid' => $student1->id, 'groupid' => $group1->id]); + $this->getDataGenerator()->create_group_member(['userid' => $student3->id, 'groupid' => $group1->id]); + $this->getDataGenerator()->create_group_member(['userid' => $student2->id, 'groupid' => $group2->id]); + + $activity = $this->getDataGenerator()->create_module( + 'workshop', + ['course' => $course->id, 'groupmode' => SEPARATEGROUPS], + ); + $cm = get_fast_modinfo($course)->get_cm($activity->cmid); + $manager = new workshop($activity, $cm, $course, $cm->context); + + $this->assertEquals(4, $manager->count_all_participants()); + $this->assertEquals(2, $manager->count_all_participants(groupids: [$group1->id])); + $this->assertEquals(1, $manager->count_all_participants(groupids: [$group2->id])); + $this->assertEquals(3, $manager->count_all_participants(groupids: [$group1->id, $group2->id])); } }