Merge branch 'MDL-85957-main' of https://github.com/sarjona/moodle
This commit is contained in:
@@ -116,7 +116,7 @@ class overview extends \core_courseformat\activityoverviewbase {
|
||||
#[\Override]
|
||||
public function get_extra_overview_items(): array {
|
||||
return [
|
||||
'studentwhoresponded' => $this->get_students_who_responded(),
|
||||
'studentwhoresponded' => $this->get_extra_students_who_responded(),
|
||||
'responded' => $this->get_extra_status_for_user(),
|
||||
];
|
||||
}
|
||||
@@ -159,12 +159,13 @@ class overview extends \core_courseformat\activityoverviewbase {
|
||||
*
|
||||
* @return overviewitem|null An overview item or null if for students.
|
||||
*/
|
||||
private function get_students_who_responded(): ?overviewitem {
|
||||
private function get_extra_students_who_responded(): ?overviewitem {
|
||||
if (!has_capability('mod/choice:readresponses', $this->cm->context)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$studentwhoanswered = $this->manager->count_all_users_answered();
|
||||
$groupids = array_keys($this->get_groups_for_filtering());
|
||||
$studentwhoanswered = $this->manager->count_all_users_answered($groupids);
|
||||
$overviewdialog = new overviewdialog(
|
||||
buttoncontent: $studentwhoanswered,
|
||||
title: get_string('totalresponses', 'mod_choice'),
|
||||
@@ -176,7 +177,7 @@ class overview extends \core_courseformat\activityoverviewbase {
|
||||
foreach ($options as $option) {
|
||||
$overviewdialog->add_item(
|
||||
$option->text,
|
||||
$this->manager->count_all_users_answered($option->id),
|
||||
$this->manager->count_all_users_answered($groupids, $option->id),
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -41,11 +41,6 @@ class manager {
|
||||
/** @var \moodle_database the database instance. */
|
||||
private \moodle_database $db;
|
||||
|
||||
/**
|
||||
* @var int $groupmode as defined in SEPARATEGROUPS, VISIBLEGROUPS, or NOGROUPS.
|
||||
*/
|
||||
private int $groupmode;
|
||||
|
||||
/**
|
||||
* Class constructor.
|
||||
*
|
||||
@@ -61,7 +56,6 @@ class manager {
|
||||
$this->context = context_module::instance($cm->id);
|
||||
$this->db = \core\di::get(\moodle_database::class);
|
||||
$this->course = $cm->get_course();
|
||||
$this->groupmode = groups_get_activity_groupmode($cm, $this->course);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -121,23 +115,41 @@ class manager {
|
||||
/**
|
||||
* Return the current count of users who have answered this choice module, that the current user can see.
|
||||
*
|
||||
* @param int[] $groupids the group identifiers to filter by, empty array means no filtering
|
||||
* @param int|null $optionid the option ID to filter by, or null to count all answers
|
||||
* @return int the number of answers that the user can see
|
||||
*/
|
||||
public function count_all_users_answered(?int $optionid = null): int {
|
||||
if (!has_any_capability(['mod/choice:view', 'mod/choice:readresponses'], $this->context)) {
|
||||
public function count_all_users_answered(
|
||||
array $groupids = [],
|
||||
?int $optionid = null,
|
||||
): int {
|
||||
if (!has_all_capabilities(['mod/choice:view', 'mod/choice:readresponses'], $this->context)) {
|
||||
return 0;
|
||||
}
|
||||
$where = ' WHERE ca.choiceid = :choiceid';
|
||||
$params = ['choiceid' => $this->instance->id];
|
||||
|
||||
$tableprefix = empty($groupids) ? '' : 'ca.';
|
||||
$select = $tableprefix . 'choiceid = :choiceid';
|
||||
$params = [
|
||||
'choiceid' => $this->instance->id,
|
||||
];
|
||||
if ($optionid) {
|
||||
$where .= ' AND ca.optionid = :optionid';
|
||||
$select .= ' AND ' . $tableprefix . 'optionid = :optionid ';
|
||||
$params['optionid'] = $optionid;
|
||||
}
|
||||
return $this->db->count_records_sql(
|
||||
'SELECT COUNT(DISTINCT ca.userid) FROM {choice_answers} ca' . $where,
|
||||
$params
|
||||
);
|
||||
|
||||
if (empty($groupids)) {
|
||||
// No groups filtering, count all users answered.
|
||||
return $this->db->count_records_select('choice_answers', $select, $params, 'COUNT(DISTINCT userid)');
|
||||
}
|
||||
|
||||
// Groups filtering is applied.
|
||||
[$gsql, $gparams] = $this->db->get_in_or_equal($groupids, SQL_PARAMS_NAMED);
|
||||
$query = "SELECT COUNT(DISTINCT ca.userid)
|
||||
FROM {choice_answers} ca, {groups_members} gm
|
||||
WHERE $select
|
||||
AND (gm.groupid $gsql OR gm.groupid = 0)
|
||||
AND ca.userid = gm.userid";
|
||||
return $this->db->count_records_sql($query, $params + $gparams);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -17,7 +17,6 @@
|
||||
namespace mod_choice\courseformat;
|
||||
|
||||
use core_courseformat\local\overview\overviewfactory;
|
||||
use core_courseformat\output\local\overview\overviewdialog;
|
||||
|
||||
/**
|
||||
* Tests for Choice integration.
|
||||
@@ -174,7 +173,7 @@ final class overview_test extends \advanced_testcase {
|
||||
],
|
||||
'Teacher' => [
|
||||
'username' => 't1',
|
||||
'expectedcount' => 2,
|
||||
'expectedcount' => 3,
|
||||
],
|
||||
];
|
||||
}
|
||||
@@ -182,28 +181,32 @@ final class overview_test extends \advanced_testcase {
|
||||
/**
|
||||
* Test get_actions_overview method.
|
||||
*
|
||||
* @param string $username The username of the user to test.
|
||||
* @param string $currentuser The current user to test.
|
||||
* @param bool $allowmultiple whether the choice allows multiple answers
|
||||
* @param bool $withanswers whether the choice will be created with answers
|
||||
* @param int $groupmode The group mode for the choice activity.
|
||||
* @param int|null $expectedcount the expected count of users who responded
|
||||
*
|
||||
* @covers ::get_actions_overview
|
||||
* @dataProvider provider_get_student_responded_count
|
||||
* @dataProvider provider_get_extra_students_who_responded
|
||||
*/
|
||||
public function test_get_students_who_responded(
|
||||
string $username,
|
||||
public function test_get_extra_students_who_responded(
|
||||
string $currentuser,
|
||||
bool $allowmultiple = false,
|
||||
bool $withanswers = true,
|
||||
int $groupmode = NOGROUPS,
|
||||
?int $expectedcount = null,
|
||||
): void {
|
||||
$this->resetAfterTest();
|
||||
[
|
||||
'users' => $users,
|
||||
'course' => $course,
|
||||
'instance' => $instance
|
||||
] = $this->setup_users_and_activity($allowmultiple, $withanswers);
|
||||
'instance' => $instance,
|
||||
] = $this->setup_users_and_activity($allowmultiple, $withanswers, $groupmode);
|
||||
$cm = get_fast_modinfo($course)->get_cm($instance->cmid);
|
||||
$this->setUser($users[$username]);
|
||||
|
||||
$this->setUser($users[$currentuser]);
|
||||
|
||||
$overview = overviewfactory::create($cm);
|
||||
$result = $overview->get_extra_overview_items();
|
||||
|
||||
@@ -239,37 +242,125 @@ final class overview_test extends \advanced_testcase {
|
||||
}
|
||||
|
||||
/**
|
||||
* Data provider for test_get_students_who_responded.
|
||||
* Data provider for test_get_extra_students_who_responded.
|
||||
*
|
||||
* @return array the data provider array
|
||||
*/
|
||||
public static function provider_get_student_responded_count(): array {
|
||||
public static function provider_get_extra_students_who_responded(): array {
|
||||
return [
|
||||
'Student' => [
|
||||
'username' => 's1',
|
||||
'currentuser' => 's1',
|
||||
'expectedcount' => null,
|
||||
],
|
||||
'Teacher - With answers - No multiple' => [
|
||||
'username' => 't1',
|
||||
// No groups.
|
||||
'No groups - Teacher - With answers - No multiple' => [
|
||||
'currentuser' => 't2',
|
||||
'allowmultiple' => false,
|
||||
'withanswers' => true,
|
||||
'expectedcount' => 2,
|
||||
'groupmode' => NOGROUPS,
|
||||
'expectedcount' => 3,
|
||||
],
|
||||
'Teacher - Without answers - No multiple' => [
|
||||
'username' => 't1',
|
||||
'No groups - Teacher - Without answers - No multiple' => [
|
||||
'currentuser' => 't2',
|
||||
'withanswers' => false,
|
||||
'groupmode' => NOGROUPS,
|
||||
'expectedcount' => 0,
|
||||
],
|
||||
'Teacher - With answers - Multiple' => [
|
||||
'username' => 't1',
|
||||
'No groups - Teacher - With answers - Multiple' => [
|
||||
'currentuser' => 't2',
|
||||
'allowmultiple' => true,
|
||||
'withanswers' => true,
|
||||
'expectedcount' => 2,
|
||||
'groupmode' => NOGROUPS,
|
||||
'expectedcount' => 3,
|
||||
],
|
||||
'Teacher - Without answers - Multiple' => [
|
||||
'username' => 't1',
|
||||
'No groups - Teacher - Without answers - Multiple' => [
|
||||
'currentuser' => 't2',
|
||||
'allowmultiple' => true,
|
||||
'withanswers' => false,
|
||||
'groupmode' => NOGROUPS,
|
||||
'expectedcount' => 0,
|
||||
],
|
||||
// Visible groups.
|
||||
'Visible groups - Teacher - With answers - No multiple' => [
|
||||
'currentuser' => 't2',
|
||||
'allowmultiple' => false,
|
||||
'withanswers' => true,
|
||||
'groupmode' => VISIBLEGROUPS,
|
||||
'expectedcount' => 3,
|
||||
],
|
||||
'Visible groups - Teacher - Without answers - No multiple' => [
|
||||
'currentuser' => 't2',
|
||||
'withanswers' => false,
|
||||
'groupmode' => VISIBLEGROUPS,
|
||||
'expectedcount' => 0,
|
||||
],
|
||||
'Visible groups - Teacher - With answers - Multiple' => [
|
||||
'currentuser' => 't2',
|
||||
'allowmultiple' => true,
|
||||
'withanswers' => true,
|
||||
'groupmode' => VISIBLEGROUPS,
|
||||
'expectedcount' => 3,
|
||||
],
|
||||
'Visible groups - Teacher - Without answers - Multiple' => [
|
||||
'currentuser' => 't2',
|
||||
'allowmultiple' => true,
|
||||
'withanswers' => false,
|
||||
'groupmode' => VISIBLEGROUPS,
|
||||
'expectedcount' => 0,
|
||||
],
|
||||
// Separate groups.
|
||||
'Separate groups - Editing teacher - With answers - No multiple' => [
|
||||
'currentuser' => 't1',
|
||||
'allowmultiple' => false,
|
||||
'withanswers' => true,
|
||||
'groupmode' => SEPARATEGROUPS,
|
||||
'expectedcount' => 3,
|
||||
],
|
||||
'Separate groups - Editing teacher - Without answers - No multiple' => [
|
||||
'currentuser' => 't1',
|
||||
'withanswers' => false,
|
||||
'groupmode' => SEPARATEGROUPS,
|
||||
'expectedcount' => 0,
|
||||
],
|
||||
'Separate groups - Editing teacher - With answers - Multiple' => [
|
||||
'currentuser' => 't1',
|
||||
'allowmultiple' => true,
|
||||
'withanswers' => true,
|
||||
'groupmode' => SEPARATEGROUPS,
|
||||
'expectedcount' => 3,
|
||||
],
|
||||
'Separate groups - Editing teacher - Without answers - Multiple' => [
|
||||
'currentuser' => 't1',
|
||||
'allowmultiple' => true,
|
||||
'withanswers' => false,
|
||||
'groupmode' => SEPARATEGROUPS,
|
||||
'expectedcount' => 0,
|
||||
],
|
||||
'Separate groups - Non-editing teacher - With answers - No multiple' => [
|
||||
'currentuser' => 't2',
|
||||
'allowmultiple' => false,
|
||||
'withanswers' => true,
|
||||
'groupmode' => SEPARATEGROUPS,
|
||||
'expectedcount' => 1,
|
||||
],
|
||||
'Separate groups - Non-editing teacher - Without answers - No multiple' => [
|
||||
'currentuser' => 't2',
|
||||
'withanswers' => false,
|
||||
'groupmode' => SEPARATEGROUPS,
|
||||
'expectedcount' => 0,
|
||||
],
|
||||
'Separate groups - Non-editing teacher - With answers - Multiple' => [
|
||||
'currentuser' => 't2',
|
||||
'allowmultiple' => true,
|
||||
'withanswers' => true,
|
||||
'groupmode' => SEPARATEGROUPS,
|
||||
'expectedcount' => 1,
|
||||
],
|
||||
'Separate groups - Non-editing teacher - Without answers - Multiple' => [
|
||||
'currentuser' => 't2',
|
||||
'allowmultiple' => true,
|
||||
'withanswers' => false,
|
||||
'groupmode' => SEPARATEGROUPS,
|
||||
'expectedcount' => 0,
|
||||
],
|
||||
];
|
||||
@@ -278,21 +369,50 @@ final class overview_test extends \advanced_testcase {
|
||||
/**
|
||||
* Setup users and activity for the tests.
|
||||
*
|
||||
* @param bool $allowmultiple whether the choice allows multiple answers.
|
||||
* @param bool $withanswers whether to create answers for the users.
|
||||
*
|
||||
* @return array
|
||||
* @param int $groupmode the group mode to use for the course.
|
||||
* @return array indexed array with 'users', 'course', 'instance' and 'groups'
|
||||
*/
|
||||
private function setup_users_and_activity(
|
||||
bool $allowmultiple = false,
|
||||
bool $withanswers = true
|
||||
bool $withanswers = true,
|
||||
int $groupmode = NOGROUPS,
|
||||
): array {
|
||||
$this->setAdminUser();
|
||||
$db = \core\di::get(\moodle_database::class);
|
||||
|
||||
$generator = $this->getDataGenerator();
|
||||
$course = $generator->create_course();
|
||||
foreach (['s1' => 'student', 's2' => 'student', 't1' => 'teacher'] as $uname => $role) {
|
||||
$users[$uname] = $generator->create_and_enrol($course, $role, ['username' => $uname]);
|
||||
// Force the group mode for the course.
|
||||
$course = $generator->create_course(['groupmode' => $groupmode, 'groupmodeforce' => 1]);
|
||||
|
||||
$data = [
|
||||
's1' => 'student',
|
||||
's2' => 'student',
|
||||
's3' => 'student', // This user does not belong to any group.
|
||||
's4' => 'student',
|
||||
't1' => 'editingteacher',
|
||||
't2' => 'teacher',
|
||||
't3' => 'teacher', // This user does not belong to any group.
|
||||
];
|
||||
foreach ($data as $username => $role) {
|
||||
$users[$username] = $generator->create_and_enrol($course, $role, ['username' => $username]);
|
||||
}
|
||||
|
||||
// Create groups.
|
||||
$groups = [
|
||||
'group1' => $generator->create_group(['courseid' => $course->id]),
|
||||
'group2' => $generator->create_group(['courseid' => $course->id]),
|
||||
];
|
||||
|
||||
// Add users to groups:
|
||||
// - group1: s1, t1, t2.
|
||||
// - group2: s2, s4.
|
||||
groups_add_member($groups['group1'], $users['s1']->id);
|
||||
groups_add_member($groups['group1'], $users['t1']->id);
|
||||
groups_add_member($groups['group1'], $users['t2']->id);
|
||||
groups_add_member($groups['group2'], $users['s2']->id);
|
||||
groups_add_member($groups['group2'], $users['s4']->id);
|
||||
|
||||
$instance = $generator->create_module('choice', [
|
||||
'course' => $course,
|
||||
'option' => ['A', 'B', 'C'],
|
||||
@@ -300,24 +420,44 @@ final class overview_test extends \advanced_testcase {
|
||||
]);
|
||||
|
||||
if ($withanswers) {
|
||||
// Create responses for the first two users.
|
||||
// Create options and responses:
|
||||
// s1: No multiple: A - Multiple: A, C.
|
||||
// s2: B.
|
||||
// s4: B.
|
||||
$db = \core\di::get(\moodle_database::class);
|
||||
$choicesid = $db->get_fieldset('choice_options', 'id', ['choiceid' => $instance->id]);
|
||||
$currentchoiceid = array_shift($choicesid); // Get the first choice.
|
||||
$generator->get_plugin_generator('mod_choice')->create_response([
|
||||
/** @var \mod_choice_generator $plugingenerator */
|
||||
$plugingenerator = $generator->get_plugin_generator('mod_choice');
|
||||
$plugingenerator->create_response([
|
||||
'choiceid' => $instance->id,
|
||||
'responses' => $currentchoiceid,
|
||||
'userid' => $users['s1']->id,
|
||||
]);
|
||||
$generator->get_plugin_generator('mod_choice')->create_response([
|
||||
if ($allowmultiple) {
|
||||
$plugingenerator->create_response([
|
||||
'choiceid' => $instance->id,
|
||||
'responses' => end($choicesid), // Get the last choice.
|
||||
'userid' => $users['s1']->id,
|
||||
]);
|
||||
}
|
||||
$plugingenerator->create_response([
|
||||
'choiceid' => $instance->id,
|
||||
'responses' => $currentchoiceid,
|
||||
'userid' => $users['s2']->id,
|
||||
]);
|
||||
$plugingenerator->create_response([
|
||||
'choiceid' => $instance->id,
|
||||
'responses' => $currentchoiceid,
|
||||
'userid' => $users['s4']->id,
|
||||
]);
|
||||
}
|
||||
|
||||
return [
|
||||
'users' => $users,
|
||||
'course' => $course,
|
||||
'instance' => $instance,
|
||||
'groups' => $groups,
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,9 +22,10 @@ use context_module;
|
||||
* Generator tests class.
|
||||
*
|
||||
* @package mod_choice
|
||||
* @category test
|
||||
* @copyright 2025 Laurent David <[email protected]>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
* @covers \mod_choice\manager
|
||||
* @covers \mod_choice\manager
|
||||
*/
|
||||
final class manager_test extends \advanced_testcase {
|
||||
/**
|
||||
@@ -53,70 +54,6 @@ final class manager_test extends \advanced_testcase {
|
||||
$this->assertEquals($cm->id, $manager->get_coursemodule()->id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Setup users and activity for testing answers retrieval.
|
||||
*
|
||||
* @param int $groupmode the group mode to use for the course.
|
||||
* @return array indexed array with 'users', 'course' and 'instance'.
|
||||
*/
|
||||
private function setup_users_and_activity(int $groupmode = NOGROUPS): array {
|
||||
$db = \core\di::get(\moodle_database::class);
|
||||
$users = [];
|
||||
$generator = $this->getDataGenerator();
|
||||
$courseparams = [];
|
||||
if ($groupmode !== NOGROUPS) {
|
||||
// Set the group mode for the course.
|
||||
$courseparams['groupmode'] = $groupmode;
|
||||
$courseparams['groupmodeforce'] = 1; // Force the group mode.
|
||||
}
|
||||
$course = $generator->create_course($courseparams);
|
||||
$data = [
|
||||
's1' => 'student',
|
||||
's2' => 'student',
|
||||
's3' => 'student',
|
||||
't1' => 'teacher',
|
||||
't2' => 'teacher',
|
||||
];
|
||||
foreach ($data as $username => $role) {
|
||||
$users[$username] = $generator->create_and_enrol($course, $role, ['username' => $username]);
|
||||
}
|
||||
|
||||
$groups = [];
|
||||
if ($groupmode !== NOGROUPS) {
|
||||
// Create a group if the group mode is not NOGROUPS.
|
||||
$groups['g1'] = $generator->create_group(['courseid' => $course->id]);
|
||||
$groups['g2'] = $generator->create_group(['courseid' => $course->id]);
|
||||
// Add users to groups: s1, and t1 to group 1, s2 to group 2.
|
||||
groups_add_member($groups['g1'], $users['s1']->id);
|
||||
groups_add_member($groups['g2'], $users['s2']->id);
|
||||
groups_add_member($groups['g1'], $users['t1']->id);
|
||||
}
|
||||
$instance = $generator->create_module('choice', [
|
||||
'course' => $course,
|
||||
'option' => ['A', 'B', 'C'],
|
||||
'allowmultiple' => 1,
|
||||
]);
|
||||
|
||||
$choicesid = $db->get_records_menu('choice_options', ['choiceid' => $instance->id], '', 'id, text');
|
||||
$choicestoid = array_flip($choicesid);
|
||||
$generator->get_plugin_generator('mod_choice')->create_response([
|
||||
'choiceid' => $instance->id,
|
||||
'responses' => [$choicestoid['A'], $choicestoid['B']], // Choose option A and B.
|
||||
'userid' => $users['s1']->id,
|
||||
]);
|
||||
$generator->get_plugin_generator('mod_choice')->create_response([
|
||||
'choiceid' => $instance->id,
|
||||
'responses' => $choicestoid['B'], // Choose option B.
|
||||
'userid' => $users['s2']->id,
|
||||
]);
|
||||
return [
|
||||
'users' => $users,
|
||||
'course' => $course,
|
||||
'instance' => $instance,
|
||||
'groups' => $groups,
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Test creating a manager instance from an instance record.
|
||||
*
|
||||
@@ -150,52 +87,50 @@ final class manager_test extends \advanced_testcase {
|
||||
/**
|
||||
* Test retrieving answers count for all users.
|
||||
*
|
||||
* @param string $username the username of the user to retrieve answers count for.
|
||||
* @param int $coursegroupmode the group mode of the course.
|
||||
* @param string|null $currentgroup the current group for the user.
|
||||
* @param int $expectedcount the expected count of answers for the user.
|
||||
* @param string $currentuser The current user to filter answers for.
|
||||
* @param int $groupmode The group mode.
|
||||
* @param array $selectedgroups The groups to filter by, empty array means no filtering.
|
||||
* @param array $expectedcount The expected count of answers for the user.
|
||||
*
|
||||
* @covers \mod_choice\manager::count_all_users_answered
|
||||
* @covers ::count_all_users_answered
|
||||
* @dataProvider provider_count_all_answers
|
||||
*/
|
||||
public function test_count_all_users_answered(
|
||||
string $username,
|
||||
int $coursegroupmode,
|
||||
?string $currentgroup,
|
||||
int $expectedcount
|
||||
string $currentuser,
|
||||
int $groupmode,
|
||||
array $selectedgroups,
|
||||
array $expectedcount
|
||||
): void {
|
||||
global $SESSION;
|
||||
|
||||
$db = \core\di::get(\moodle_database::class);
|
||||
[
|
||||
'users' => $users,
|
||||
'instance' => $instance,
|
||||
'course' => $course,
|
||||
'groups' => $groups,
|
||||
] = $this->setup_users_and_activity($coursegroupmode);
|
||||
$manager = \mod_choice\manager::create_from_instance($instance);
|
||||
$this->setUser($users[$username]);
|
||||
if (!is_null($currentgroup) && $coursegroupmode !== NOGROUPS) {
|
||||
$group = $groups[$currentgroup];
|
||||
$SESSION->activegroup[$course->id][$coursegroupmode][$course->defaultgroupingid] = $group->id;
|
||||
}
|
||||
$count = $manager->count_all_users_answered();
|
||||
$this->assertEquals($expectedcount, $count);
|
||||
'groups' => $allgroups,
|
||||
] = $this->setup_users_and_activity($groupmode);
|
||||
|
||||
// Check answers count for each option.
|
||||
$options = $db->get_records_menu('choice_options', ['choiceid' => $instance->id], '', 'id, text');
|
||||
foreach ($options as $optionid => $optiontext) {
|
||||
$count = $manager->count_all_users_answered($optionid);
|
||||
if ($optiontext === 'A') {
|
||||
$this->assertEquals(1, $count);
|
||||
} else if ($optiontext === 'B') {
|
||||
$this->assertEquals(2, $count);
|
||||
} else {
|
||||
// Option C has no answers.
|
||||
$this->assertEquals(0, $count);
|
||||
$this->setUser($users[$currentuser]);
|
||||
$manager = \mod_choice\manager::create_from_instance($instance);
|
||||
|
||||
$groups = [];
|
||||
if (!empty($selectedgroups)) {
|
||||
foreach ($selectedgroups as $group) {
|
||||
if ($group === 'unexisting') {
|
||||
$groups = [666];
|
||||
} else {
|
||||
$groups[] = $allgroups[$group]->id;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$count = $manager->count_all_users_answered($groups);
|
||||
$this->assertEquals($expectedcount['all'], $count);
|
||||
|
||||
// Check answers count for each option.
|
||||
$db = \core\di::get(\moodle_database::class);
|
||||
$options = $db->get_records_menu('choice_options', ['choiceid' => $instance->id], '', 'id, text');
|
||||
foreach ($options as $optionid => $optiontext) {
|
||||
$count = $manager->count_all_users_answered($groups, $optionid);
|
||||
$this->assertEquals($expectedcount[$optiontext], $count);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -205,50 +140,93 @@ final class manager_test extends \advanced_testcase {
|
||||
*/
|
||||
public static function provider_count_all_answers(): array {
|
||||
return [
|
||||
'Teacher in a group - No group mode' => [
|
||||
'username' => 't1',
|
||||
'coursegroupmode' => NOGROUPS,
|
||||
'currentgroup' => null,
|
||||
'expectedcount' => 2,
|
||||
'Teacher - No group' => [
|
||||
'currentuser' => 't1',
|
||||
'groupmode' => NOGROUPS,
|
||||
'selectedgroups' => [],
|
||||
'expectedcount' => [
|
||||
'all' => 3,
|
||||
'A' => 1,
|
||||
'B' => 3,
|
||||
'C' => 0,
|
||||
],
|
||||
],
|
||||
// This test about SEPARATEGROUPS it will be the subject of an follow up ticket (MDL-85852).
|
||||
'Teacher in a group - Separate group mode' => [
|
||||
'username' => 't1',
|
||||
'coursegroupmode' => SEPARATEGROUPS,
|
||||
'currentgroup' => null,
|
||||
'expectedcount' => 2,
|
||||
'Teacher - Visible groups' => [
|
||||
'currentuser' => 't1',
|
||||
'groupmode' => VISIBLEGROUPS,
|
||||
'selectedgroups' => [],
|
||||
'expectedcount' => [
|
||||
'all' => 3,
|
||||
'A' => 1,
|
||||
'B' => 3,
|
||||
'C' => 0,
|
||||
],
|
||||
],
|
||||
'Teacher in a group - Separate group mode - Group1' => [
|
||||
'username' => 't1',
|
||||
'coursegroupmode' => SEPARATEGROUPS,
|
||||
'currentgroup' => 'g1',
|
||||
'expectedcount' => 2,
|
||||
'Teacher - Separate groups (all)' => [
|
||||
'currentuser' => 't1',
|
||||
'groupmode' => SEPARATEGROUPS,
|
||||
'selectedgroups' => [],
|
||||
'expectedcount' => [
|
||||
'all' => 3,
|
||||
'A' => 1,
|
||||
'B' => 3,
|
||||
'C' => 0,
|
||||
],
|
||||
],
|
||||
'Teacher in a group - Visible group mode' => [
|
||||
'username' => 't1',
|
||||
'coursegroupmode' => VISIBLEGROUPS,
|
||||
'currentgroup' => null,
|
||||
'expectedcount' => 2,
|
||||
'Teacher - Separate groups (group1)' => [
|
||||
'currentuser' => 't1',
|
||||
'groupmode' => SEPARATEGROUPS,
|
||||
'selectedgroups' => ['group1'],
|
||||
'expectedcount' => [
|
||||
'all' => 1,
|
||||
'A' => 1,
|
||||
'B' => 1,
|
||||
'C' => 0,
|
||||
],
|
||||
],
|
||||
// Teacher 2 does not belong to any group.
|
||||
'Teacher without group - No group mode' => [
|
||||
'username' => 't2',
|
||||
'coursegroupmode' => NOGROUPS,
|
||||
'currentgroup' => null,
|
||||
'expectedcount' => 2,
|
||||
'Teacher - Separate groups (group2)' => [
|
||||
'currentuser' => 't1',
|
||||
'groupmode' => SEPARATEGROUPS,
|
||||
'selectedgroups' => ['group2'],
|
||||
'expectedcount' => [
|
||||
'all' => 2,
|
||||
'A' => 0,
|
||||
'B' => 2,
|
||||
'C' => 0,
|
||||
],
|
||||
],
|
||||
// These tests about SEPARATEGROUPS will be the subject of an follow up ticket (MDL-85852).
|
||||
'Teacher without group - Separate group mode' => [
|
||||
'username' => 't2',
|
||||
'coursegroupmode' => SEPARATEGROUPS,
|
||||
'currentgroup' => null,
|
||||
'expectedcount' => 2,
|
||||
'Teacher - Separate groups (group1, group2)' => [
|
||||
'currentuser' => 't1',
|
||||
'groupmode' => SEPARATEGROUPS,
|
||||
'selectedgroups' => ['group1', 'group2'],
|
||||
'expectedcount' => [
|
||||
'all' => 3,
|
||||
'A' => 1,
|
||||
'B' => 3,
|
||||
'C' => 0,
|
||||
],
|
||||
],
|
||||
'Teacher without group - Visible group mode' => [
|
||||
'username' => 't2',
|
||||
'coursegroupmode' => VISIBLEGROUPS,
|
||||
'currentgroup' => null,
|
||||
'expectedcount' => 2,
|
||||
'Student' => [
|
||||
'currentuser' => 's1',
|
||||
'groupmode' => NOGROUPS,
|
||||
'selectedgroups' => [],
|
||||
'expectedcount' => [
|
||||
'all' => 0, // Students cannot see the answers count.
|
||||
'A' => 0,
|
||||
'B' => 0,
|
||||
'C' => 0,
|
||||
],
|
||||
],
|
||||
'Unexisting group - Separate groups' => [
|
||||
'currentuser' => 't1',
|
||||
'groupmode' => SEPARATEGROUPS,
|
||||
'selectedgroups' => ['unexisting'],
|
||||
'expectedcount' => [
|
||||
'all' => 0,
|
||||
'A' => 0,
|
||||
'B' => 0,
|
||||
'C' => 0,
|
||||
],
|
||||
],
|
||||
];
|
||||
}
|
||||
@@ -290,4 +268,81 @@ final class manager_test extends \advanced_testcase {
|
||||
$options = $manager->get_options();
|
||||
$this->assertCount(1, $options);
|
||||
}
|
||||
|
||||
/**
|
||||
* Setup users and activity for testing answers retrieval.
|
||||
*
|
||||
* @param int $groupmode the group mode to use for the course.
|
||||
* @return array indexed array with 'users', 'course', 'instance' and 'groups'.
|
||||
*/
|
||||
private function setup_users_and_activity(int $groupmode = NOGROUPS): array {
|
||||
$db = \core\di::get(\moodle_database::class);
|
||||
$users = [];
|
||||
$generator = $this->getDataGenerator();
|
||||
|
||||
// Force the group mode for the course.
|
||||
$course = $generator->create_course(['groupmode' => $groupmode, 'groupmodeforce' => 1]);
|
||||
$data = [
|
||||
's1' => 'student',
|
||||
's2' => 'student',
|
||||
's3' => 'student', // This user does not belong to any group.
|
||||
's4' => 'student',
|
||||
't1' => 'editingteacher',
|
||||
't2' => 'teacher', // This user does not belong to any group.
|
||||
];
|
||||
foreach ($data as $username => $role) {
|
||||
$users[$username] = $generator->create_and_enrol($course, $role, ['username' => $username]);
|
||||
}
|
||||
|
||||
// Create groups.
|
||||
$groups = [
|
||||
'group1' => $generator->create_group(['courseid' => $course->id]),
|
||||
'group2' => $generator->create_group(['courseid' => $course->id]),
|
||||
];
|
||||
|
||||
// Add users to groups:
|
||||
// - group1: s1, t1.
|
||||
// - group2: s2, s4.
|
||||
groups_add_member($groups['group1'], $users['s1']->id);
|
||||
groups_add_member($groups['group1'], $users['t1']->id);
|
||||
groups_add_member($groups['group2'], $users['s2']->id);
|
||||
groups_add_member($groups['group2'], $users['s4']->id);
|
||||
|
||||
$instance = $generator->create_module('choice', [
|
||||
'course' => $course,
|
||||
'option' => ['A', 'B', 'C'],
|
||||
'allowmultiple' => 1,
|
||||
]);
|
||||
|
||||
// Create options and responses:
|
||||
// s1: A, B.
|
||||
// s2: B.
|
||||
// s4: B.
|
||||
$choicesid = $db->get_records_menu('choice_options', ['choiceid' => $instance->id], '', 'id, text');
|
||||
$choicestoid = array_flip($choicesid);
|
||||
/** @var \mod_choice_generator $plugingenerator */
|
||||
$plugingenerator = $generator->get_plugin_generator('mod_choice');
|
||||
$plugingenerator->create_response([
|
||||
'choiceid' => $instance->id,
|
||||
'responses' => [$choicestoid['A'], $choicestoid['B']],
|
||||
'userid' => $users['s1']->id,
|
||||
]);
|
||||
$plugingenerator->create_response([
|
||||
'choiceid' => $instance->id,
|
||||
'responses' => $choicestoid['B'],
|
||||
'userid' => $users['s2']->id,
|
||||
]);
|
||||
$plugingenerator->create_response([
|
||||
'choiceid' => $instance->id,
|
||||
'responses' => $choicestoid['B'],
|
||||
'userid' => $users['s4']->id,
|
||||
]);
|
||||
|
||||
return [
|
||||
'users' => $users,
|
||||
'course' => $course,
|
||||
'instance' => $instance,
|
||||
'groups' => $groups,
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user