diff --git a/public/course/format/classes/output/local/overview/overviewtable.php b/public/course/format/classes/output/local/overview/overviewtable.php index 0a8d4d663bf..bccd9f8ea8b 100644 --- a/public/course/format/classes/output/local/overview/overviewtable.php +++ b/public/course/format/classes/output/local/overview/overviewtable.php @@ -228,6 +228,34 @@ class overviewtable implements externable, named_templatable, renderable { * @return array An associative array containing the overview items for the activity. */ private function load_overview_items_from_activity(activityoverviewbase $overview): array { + $row = $this->get_activity_columns($overview); + $row = array_filter($row, function ($item) { + return $item !== null; + }); + + $this->register_columns($row); + $result = []; + foreach ($row as $key => $item) { + $item->set_key($key); + $result[$key] = $item; + } + return $result; + } + + /** + * Get the columns for the activity overview. + * + * This method retrieves the columns that can be displayed in the overview table + * for a specific activity. However, column with null values may be filtered if + * all the activities do not have any content for that column. + * + * @param activityoverviewbase $overview The activity overview instance. + * @return array An associative array of column data. + */ + private function get_activity_columns(activityoverviewbase $overview): array { + // It is highly improbable that an activity has an error (usually because of an erroneous group + // configuration). For those cases, we only use the activity name and prevent the plugin from + // doing any more calculations. if ($overview->has_error()) { return ['name' => $overview->get_name_overview()]; } @@ -250,18 +278,7 @@ class overviewtable implements externable, named_templatable, renderable { // Actions are always the last column, if any. $row['actions'] = $overview->get_actions_overview(); - $row = array_filter($row, function ($item) { - return $item !== null; - }); - - $this->register_columns($row); - - $result = []; - foreach ($row as $key => $item) { - $item->set_key($key); - $result[$key] = $item; - } - return $result; + return $row; } /** diff --git a/public/course/format/tests/external/get_overview_information_test.php b/public/course/format/tests/external/get_overview_information_test.php index 4d568b1730d..e7459718231 100644 --- a/public/course/format/tests/external/get_overview_information_test.php +++ b/public/course/format/tests/external/get_overview_information_test.php @@ -143,4 +143,87 @@ final class get_overview_information_test extends \externallib_advanced_testcase } return null; } + + /** + * Test the webservice when the group configuration is erroneous. + * In those cases, the table should only return the activity name. + * + * @return void + */ + public function test_execute_when_group_error(): void { + $this->resetAfterTest(); + + $generator = $this->getDataGenerator(); + $course = $generator->create_course(); + $activityfail = $generator->create_module('assign', ['course' => $course->id, 'groupmode' => SEPARATEGROUPS]); + $user = $generator->create_and_enrol($course, 'student'); + $generator->create_group(['courseid' => $course->id, 'name' => 'g1']); + $generator->create_group(['courseid' => $course->id, 'name' => 'g2']); + + $this->setUser($user); + + $result = get_overview_information::execute($course->id, 'assign'); + $result = external_api::clean_returnvalue(get_overview_information::execute_returns(), $result); + + $this->assertEquals($course->id, $result['courseid']); + $this->assertEquals(true, $result['hasintegration']); + + $this->assertCount(1, $result['headers']); + $headertelement = $this->find_by_attribute($result['headers'], 'key', 'name'); + $this->assertEquals(get_string('name'), $headertelement['name']); + $this->assertEquals('name', $headertelement['key']); + + $this->assertCount(1, $result['activities']); + $activity = $this->find_by_attribute($result['activities'], 'cmid', (int) $activityfail->cmid); + $this->assertCount(1, $activity['items']); + $this->assertEquals(true, $activity['haserror']); + $namecell = $activity['items'][0]; + $namecell = $activity['items'][0]; + $this->assertEquals('name', $namecell['key']); + $this->assertEquals(get_string('name'), $namecell['name']); + + // Add a second activity to validate the overview table is populated with all columns now. + $activityok = $generator->create_module('assign', ['course' => $course->id, 'groupmode' => VISIBLEGROUPS]); + + $result = get_overview_information::execute($course->id, 'assign'); + $result = external_api::clean_returnvalue(get_overview_information::execute_returns(), $result); + + $this->assertEquals($course->id, $result['courseid']); + $this->assertEquals(true, $result['hasintegration']); + + $this->assertCount(3, $result['headers']); + $headertelement = $this->find_by_attribute($result['headers'], 'key', 'name'); + $this->assertEquals(get_string('name'), $headertelement['name']); + $this->assertEquals('name', $headertelement['key']); + $headertelement = $this->find_by_attribute($result['headers'], 'key', 'submissionstatus'); + $this->assertEquals(get_string('submissionstatus', 'assign'), $headertelement['name']); + $this->assertEquals('submissionstatus', $headertelement['key']); + $headertelement = $this->find_by_attribute($result['headers'], 'key', 'Grade'); + $this->assertEquals(get_string('gradenoun'), $headertelement['name']); + $this->assertEquals('Grade', $headertelement['key']); + + $this->assertCount(2, $result['activities']); + + // The activity with the group error should be the same. + $activity = $this->find_by_attribute($result['activities'], 'cmid', (int) $activityfail->cmid); + $this->assertCount(1, $activity['items']); + $this->assertEquals(true, $activity['haserror']); + $namecell = $activity['items'][0]; + $namecell = $activity['items'][0]; + $this->assertEquals('name', $namecell['key']); + $this->assertEquals(get_string('name'), $namecell['name']); + + $activity = $this->find_by_attribute($result['activities'], 'cmid', (int) $activityok->cmid); + $this->assertCount(3, $activity['items']); + $this->assertEquals(false, $activity['haserror']); + $namecell = $activity['items'][0]; + $this->assertEquals('name', $namecell['key']); + $this->assertEquals(get_string('name'), $namecell['name']); + $submissionstatuscell = $this->find_by_attribute($activity['items'], 'key', 'submissionstatus'); + $this->assertEquals('submissionstatus', $submissionstatuscell['key']); + $this->assertEquals(get_string('submissionstatus', 'assign'), $submissionstatuscell['name']); + $gradecell = $this->find_by_attribute($activity['items'], 'key', 'Grade'); + $this->assertEquals('Grade', $gradecell['key']); + $this->assertEquals(get_string('gradenoun'), $gradecell['name']); + } }