Merge branch 'MDL-83895-main' of https://github.com/aanabit/moodle

This commit is contained in:
cescobedo
2025-06-23 15:14:31 +02:00
10 changed files with 763 additions and 61 deletions
@@ -0,0 +1,9 @@
issueNumber: MDL-83896
notes:
core_courseformat:
- message: >-
Added new core_courseformat\output\local\overview\overviewdialog output
class to create dialog elements in the course overview page. Overview
dialog will display a combination of title, description and a list
of items (label: value).
type: improved
@@ -0,0 +1,124 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
namespace core_courseformat\output\local\overview;
use core\output\local\dropdown\dialog;
use stdClass;
/**
* Class to render an overview dialog element.
*
* @package core_courseformat
* @copyright 2025 Mikel Martín <[email protected]>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class overviewdialog extends dialog {
/** @var stdClass[] The list of the items. */
protected array $items;
/**
* Constructor.
*
* The definition object could contain the following keys:
* - classes: component CSS classes.
* - buttonclasses: the button CSS classes.
* - dialogwidth: the dropdown width.
* - extras: extra HTML attributes (attribute => value).
*
* @param string $buttoncontent the button content
* @param string $title the overview dialog content title
* @param string $description the overview dialog content description
* @param array $definition an optional array of the element definition
*/
public function __construct(
string $buttoncontent,
/** @var string The title of the overview dialog content. */
protected string $title = '',
/** @var string The title of the overview dialog content. */
protected string $description = '',
array $definition = []
) {
parent::__construct($buttoncontent, '', $definition);
$this->items = [];
}
/**
* Set the items to be displayed in the overview dialog.
*
* @param string $label the label of the item
* @param string $value the value of the item
* @return overviewdialog
*/
public function add_item(string $label, string $value): self {
$this->items[] = (object) [
'label' => $label,
'value' => $value,
];
return $this;
}
/**
* Set the title of the overview dialog content.
*
* @param string $title the title to set
* @return overviewdialog
*/
public function set_title(string $title): self {
$this->title = $title;
return $this;
}
/**
* Set the description of the overview dialog content.
*
* @param string $description the description to set
* @return overviewdialog
*/
public function set_description(string $description): self {
$this->description = $description;
return $this;
}
/**
* Export this data so it can be used as the context for a mustache template.
*
* @param \renderer_base $output typically, the renderer that's calling this function
* @return array data context for a mustache template
*/
public function export_for_template(\renderer_base $output): array {
$data = [
...parent::export_for_template($output),
'title' => $this->title,
'items' => $this->items,
'hasitems' => count($this->items),
'description' => $this->description,
];
return $data;
}
/**
* Get the name of the template to use for this templatable.
*
* @param \renderer_base $renderer The renderer requesting the template name
* @return string the template name
*/
public function get_template_name(\renderer_base $renderer): string {
return 'core_courseformat/local/overview/overviewdialog';
}
}
@@ -0,0 +1,65 @@
{{!
This file is part of Moodle - http://moodle.org/
Moodle is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Moodle is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Moodle. If not, see <http://www.gnu.org/licenses/>.
}}
{{!
@template core_courseformat/local/overview/overviewdialog
Shows an overview dialog.
Example context (json):
{
"buttoncontent" : "Trigger button",
"title": "Total Attempts",
"description": "This shows the total attempts made by the user in the course.",
"hasitems": true,
"items": [
{
"label": "Allowed Attempts",
"value": 3
},
{
"label": "Average Attempts",
"value": "Max reached"
}
]
}
}}
{{< core/local/dropdown/dialog }}
{{$ dialogcontent }}
<div class="px-3">
{{#title}}
<span class="fw-bold">{{title}}</span>
{{/title}}
{{#description}}
<div class="mt-2 mb-3">{{{description}}}</div>
{{/description}}
{{#hasitems}}
<ul class="my-2">
{{#items}}
<li>
{{#str}}
labelvalue, core, {
"label": {{#quote}}{{label}}{{/quote}},
"value": {{#quote}}<span class="fw-bold">{{value}}</span>{{/quote}}
}
{{/str}}
</li>
{{/items}}
</ul>
{{/hasitems}}
</div>
{{/ dialogcontent }}
{{/ core/local/dropdown/dialog }}
@@ -117,7 +117,7 @@ final class overviewfactory_test extends \advanced_testcase {
],
'h5pactivity' => [
'resourcetype' => 'h5pactivity',
'expected' => resourceoverview::class,
'expected' => \mod_h5pactivity\courseformat\overview::class,
],
'lesson' => [
'resourcetype' => 'lesson',
@@ -72,7 +72,7 @@ final class missingoverviewnotice_test extends \advanced_testcase {
'folder' => ['modname' => 'folder', 'expectempty' => false],
'forum' => ['modname' => 'forum', 'expectempty' => false],
'glossary' => ['modname' => 'glossary', 'expectempty' => true],
'h5pactivity' => ['modname' => 'h5pactivity', 'expectempty' => false],
'h5pactivity' => ['modname' => 'h5pactivity', 'expectempty' => true],
'imscp' => ['modname' => 'imscp', 'expectempty' => false],
'label' => ['modname' => 'label', 'expectempty' => false],
'lesson' => ['modname' => 'lesson', 'expectempty' => false],
@@ -0,0 +1,204 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
namespace mod_h5pactivity\courseformat;
use cm_info;
use core_courseformat\local\overview\overviewitem;
use core\output\action_link;
use core\output\local\properties\text_align;
use core\output\local\properties\button;
use core\url;
use core_courseformat\output\local\overview\overviewdialog;
use mod_h5pactivity\local\manager;
/**
* H5P activity overview integration.
*
* @package mod_h5pactivity
* @copyright 2025 Amaia Anabitarte <[email protected]>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class overview extends \core_courseformat\activityoverviewbase {
/** @var manager H5P activity manager. */
private $manager;
/**
* Constructor.
*
* @param cm_info $cm the course module instance.
* @param \core\output\renderer_helper $rendererhelper the renderer helper.
* @param \core_string_manager $stringmanager the string manager.
*/
public function __construct(
cm_info $cm,
/** @var \core\output\renderer_helper $rendererhelper the renderer helper */
protected readonly \core\output\renderer_helper $rendererhelper,
/** @var \core_string_manager $stringmanager the string manager */
protected readonly \core_string_manager $stringmanager,
) {
parent::__construct($cm);
$this->manager = manager::create_from_coursemodule($cm);
}
#[\Override]
public function get_actions_overview(): ?overviewitem {
if (!$this->manager->can_view_all_attempts()) {
return null;
}
$viewresults = $this->stringmanager->get_string('viewresults', 'mod_h5pactivity');
$content = new action_link(
url: new url('/mod/h5pactivity/report.php', ['id' => $this->cm->id]),
text: $viewresults,
attributes: ['class' => button::SECONDARY_OUTLINE->classes()],
);
return new overviewitem(
name: $this->stringmanager->get_string('actions'),
value: '',
content: $content,
textalign: text_align::CENTER,
);
}
#[\Override]
public function get_extra_overview_items(): array {
global $USER;
if (!$this->manager->can_view_own_attempts() && $this->manager->can_view_all_attempts()) {
return [];
}
if (!$this->manager->can_view_all_attempts()) {
return [
'myattempts' => $this->get_extra_userattempts_overview($USER->id),
];
}
return [
'h5ptype' => $this->get_extra_h5ptype_overview(),
'attempted' => $this->get_extra_studentsattempted_overview(),
'totalattempts' => $this->get_extra_totalattempts_overview(),
];
}
/**
* Get the attempts of the given user.
*
* @param int $userid The user to return the attempts from.
* @return overviewitem The overview item.
*/
private function get_extra_userattempts_overview(int $userid): overviewitem {
$attempts = $this->manager->count_attempts($userid);
return new overviewitem(
name: $this->stringmanager->get_string('attempts', 'mod_h5pactivity'),
value: $attempts,
content: $attempts ?? '-',
textalign: text_align::CENTER,
);
}
/**
* Get the students who attempted.
*
* @return overviewitem The overview item.
*/
private function get_extra_studentsattempted_overview(): overviewitem {
$attempts = $this->manager->count_users_attempts();
$participants = get_users_by_capability($this->context, 'mod/h5pactivity:submit');
$params = [
'count' => count($attempts),
'total' => count($participants),
];
return new overviewitem(
name: $this->stringmanager->get_string('attempted', 'mod_h5pactivity'),
value: count($attempts),
content: $this->stringmanager->get_string('count_of_total', 'core', $params),
textalign: text_align::CENTER,
);
}
/**
* Get the "Total attempts" colum data.
*
* @return overviewitem The overview item.
*/
private function get_extra_totalattempts_overview(): overviewitem {
$totalattempts = $this->manager->count_attempts();
$totalusers = $this->manager->count_users_attempts();
$content = '-';
if ($totalusers && count($totalusers) > 0 && $totalattempts) {
$averageattempts = (int) round($totalattempts / count($totalusers));
$content = new overviewdialog(
buttoncontent: $totalattempts,
title: $this->stringmanager->get_string('totalattempts', 'mod_h5pactivity'),
definition: ['buttonclasses' => button::SECONDARY_OUTLINE->classes() . ' dropdown-toggle'],
);
$method = $this->manager::get_grading_methods()[$this->manager->get_instance()->grademethod];
$content->add_item($this->stringmanager->get_string('gradingmethod', 'grading'), $method);
$content->add_item($this->stringmanager->get_string('averageattempts', 'mod_h5pactivity'), $averageattempts);
}
return new overviewitem(
name: $this->stringmanager->get_string('totalattempts', 'mod_h5pactivity'),
value: $totalattempts,
content: $content,
);
}
/**
* Get the H5P content type.
*
* @return overviewitem The overview item.
*/
private function get_extra_h5ptype_overview(): overviewitem {
$fs = get_file_storage();
$files = $fs->get_area_files($this->context->id, 'mod_h5pactivity', 'package', 0, 'id', false);
$file = reset($files);
$h5p = \core_h5p\api::get_content_from_pathnamehash($file->get_pathnamehash());
$unknonwoverview = new overviewitem(
name: $this->stringmanager->get_string('contenttype', 'mod_h5pactivity'),
value: $this->stringmanager->get_string('unknowntype', 'mod_h5pactivity'),
content: $this->stringmanager->get_string('unknowntype', 'mod_h5pactivity'),
);
if (empty($h5p)) {
return $unknonwoverview;
}
$h5plib = \core_h5p\api::get_library($h5p->mainlibraryid);
// If the content is not yet deployed we cannot show the content type.
if (empty($h5plib)) {
return $unknonwoverview;
}
return new overviewitem(
name: $this->stringmanager->get_string('contenttype', 'mod_h5pactivity'),
value: $h5plib->title,
content: $h5plib->title,
);
}
}
+2 -59
View File
@@ -25,62 +25,5 @@
require(__DIR__.'/../../config.php');
require_once(__DIR__.'/lib.php');
$id = required_param('id', PARAM_INT);
$course = $DB->get_record('course', ['id' => $id], '*', MUST_EXIST);
require_course_login($course);
$coursecontext = context_course::instance($course->id);
$event = \mod_h5pactivity\event\course_module_instance_list_viewed::create(['context' => $coursecontext]);
$event->add_record_snapshot('course', $course);
$event->trigger();
$PAGE->set_url('/mod/h5pactivity/index.php', ['id' => $id]);
$PAGE->set_title(format_string($course->fullname));
$PAGE->set_heading(format_string($course->fullname));
$PAGE->set_context($coursecontext);
echo $OUTPUT->header();
$modulenameplural = get_string('modulenameplural', 'mod_h5pactivity');
echo $OUTPUT->heading($modulenameplural);
$h5pactivities = get_all_instances_in_course('h5pactivity', $course);
if (empty($h5pactivities)) {
notice(get_string('thereareno', 'moodle'), new moodle_url('/course/view.php', ['id' => $course->id]));
exit;
}
$table = new html_table();
$table->attributes['class'] = 'table generaltable mod_index';
$align = ['center', 'left'];
if ($course->format == 'weeks' || $course->format == 'topics') {
$table->head = [get_string('section'), get_string('name')];
$table->align = ['center', 'left'];
} else {
$table->head = [get_string('name')];
$table->align = ['left'];
}
foreach ($h5pactivities as $h5pactivity) {
$attributes = [];
if (!$h5pactivity->visible) {
$attributes['class'] = 'dimmed';
}
$link = html_writer::link(
new moodle_url('/mod/h5pactivity/view.php', ['id' => $h5pactivity->coursemodule]),
format_string($h5pactivity->name, true),
$attributes);
if ($course->format == 'weeks' or $course->format == 'topics') {
$table->data[] = [$h5pactivity->section, $link];
} else {
$table->data[] = [$link];
}
}
echo html_writer::table($table);
echo $OUTPUT->footer();
$courseid = required_param('id', PARAM_INT);
\core_courseformat\activityoverviewbase::redirect_to_overview_page($courseid, 'h5pactivity');
+6
View File
@@ -37,6 +37,7 @@ $string['answer_text'] = 'Answer text';
$string['answer_noanswer'] = 'None';
$string['areapackage'] = 'Package file';
$string['attempt'] = 'Attempt';
$string['attempted'] = 'Students who attempted';
$string['attempt_average'] = 'Attempts average scored';
$string['attempt_answer'] = 'Attempt answer';
$string['attempt_completion_no'] = 'This attempt is not marked as completed';
@@ -53,10 +54,12 @@ $string['attempts'] = 'Attempts';
$string['attempts_report_header_label'] = 'Attempts ({$a})';
$string['attempts_report'] = 'Attempts report';
$string['attempts_none'] = 'This user has no attempts to display.';
$string['averageattempts'] = 'Average attempts per student';
$string['choice'] = 'Choice';
$string['completion'] = 'Completion';
$string['contentbank'] = 'More information about the content bank';
$string['contentbank_help'] = 'In the content bank you can create and store content using several authoring tools, including an integrated H5P creator.';
$string['contenttype'] = 'H5P type';
$string['correct_answer'] = 'Correct answer';
$string['deleteallattempts'] = 'All H5P attempts';
$string['displayexport'] = 'Allow download';
@@ -140,12 +143,15 @@ $string['score_out_of'] = '{$a->rawscore} out of {$a->maxscore}';
$string['search:activity'] = 'H5P - activity information';
$string['startdate'] = 'Start date';
$string['statement_received'] = 'xAPI statement received';
$string['totalattempts'] = 'Total attempts';
$string['totalscore'] = 'Total score';
$string['trackingdisabled'] = 'Attempt tracking is not enabled for this activity.';
$string['trackingdisabled_enable'] = 'Attempt tracking is not enabled for this activity. You can enable it in <a href="{$a}">Settings</a>.';
$string['tracking_messages'] = 'Some H5P provide attempt tracking data for advanced reporting such as number of attempts, responses and grades. Note: Some H5P don\'t provide attempt tracking data. In such cases, the following settings will have no effect.';
$string['true'] = 'True';
$string['unknowntype'] = 'Unknown H5P type';
$string['usecontentbank'] = 'Use the <a href="{$a}" target="_blank">content bank (opens in new window)</a> to manage your H5P files';
$string['view'] = 'View';
$string['viewattempts'] = 'View attempts ({$a})';
$string['viewresults'] = 'View results';
$string['view_report'] = 'View report';
@@ -0,0 +1,104 @@
@mod @mod_h5pactivity
Feature: Testing overview integration in H5P activity
In order to summarize the H5P activity
As a user
I need to be able to see the H5P activity overview
Background:
Given the following "users" exist:
| username | firstname | lastname | email |
| student1 | Student | 1 | student1@example.com |
| student2 | Student | 2 | student2@example.com |
| student3 | Student | 3 | student3@example.com |
| teacher1 | Teacher | 1 | teacher1@example.com |
And the following "courses" exist:
| fullname | shortname | category | enablecompletion |
| Course 1 | C1 | 0 | 1 |
And the following "course enrolments" exist:
| user | course | role |
| teacher1 | C1 | editingteacher |
| student1 | C1 | student |
| student2 | C1 | student |
| student3 | C1 | student |
And the following "activity" exists:
| course | C1 |
| activity | h5pactivity |
| name | H5P activity |
| intro | description |
| packagefilepath | h5p/tests/fixtures/find-the-words.h5p |
| idnumber | h5p |
| completion | 1 |
| enabletracking | 1 |
| reviewmode | 1 |
| grademethod | 2 |
And the following "activity" exists:
| course | C1 |
| activity | h5pactivity |
| name | Empty H5P activity |
| intro | empty |
| idnumber | empty |
And the following "mod_h5pactivity > attempts" exist:
| user | h5pactivity | attempt | interactiontype | rawscore | maxscore | duration | completion | success |
# student1.
| student1 | H5P activity | 1 | choice | 2 | 2 | 1 | 1 | 1 |
| student1 | H5P activity | 1 | compound | 2 | 2 | 4 | 1 | 1 |
| student1 | H5P activity | 2 | choice | 0 | 2 | 1 | 1 | 0 |
| student1 | H5P activity | 2 | compound | 0 | 2 | 4 | 1 | 0 |
| student1 | H5P activity | 3 | matching | 2 | 2 | 1 | 1 | 1 |
| student1 | H5P activity | 3 | compound | 2 | 2 | 4 | 1 | 1 |
| student1 | H5P activity | 4 | true-false | 2 | 2 | 1 | 1 | 1 |
| student1 | H5P activity | 4 | compound | 2 | 2 | 4 | 1 | 1 |
# student2.
| student2 | H5P activity | 1 | compound | 0 | 2 | 1 | 1 | 0 |
# We need to navigate to the activity to deploy the H5P file.
And I am on the "H5P activity" "h5pactivity activity" page logged in as admin
And I log out
Scenario: The H5P activity overview report should generate log events
Given I am on the "Course 1" "course > activities > h5pactivity" page logged in as "teacher1"
And I am on the "Course 1" "course" page logged in as "teacher1"
And I navigate to "Reports" in current page administration
And I click on "Logs" "link"
When I click on "Get these logs" "button"
Then I should see "Course activities overview page viewed"
And I should see "viewed the instance list for the module 'h5pactivity'"
@javascript
Scenario: Students can see relevant columns in the H5P activity overview
Given I am on the "Course 1" "course > activities > h5pactivity" page logged in as student1
# Check columns.
When I should see "Completion status" in the "h5pactivity_overview_collapsible" "region"
# Check column values.
Then the following should exist in the "Table listing all H5P activities" table:
| Name | Attempts | Grade |
| H5P activity | 4 | 75.00 |
| Empty H5P activity | 0 | - |
@javascript
Scenario: Teachers can see relevant columns in the H5P activity overview
Given I am on the "Course 1" "course > activities > h5pactivity" page logged in as teacher1
# Check columns.
And I should see "Total attempts" in the "h5pactivity_overview_collapsible" "region"
# Check column values.
And the following should exist in the "Table listing all H5P activities" table:
| Name | H5P type | Students who attempted | Total attempts | Actions |
| H5P activity | Find The Words | 2 of 3 | 5 | View results |
| Empty H5P activity | Unknown H5P type | 0 of 3 | - | View results |
# Check the Total attempts value.
And I should see "-" in the "Empty H5P activity" "table_row"
When I click on "5" "button" in the "H5P activity" "table_row"
Then I should see "Grading method: Average grade"
And I should see "Average attempts per student: 3"
# Check the View results link.
And I click on "View results" "link" in the "H5P activity" "table_row"
And I should see "Attempts (5)"
Scenario: The H5P activity index redirect to the activities overview
Given I log in as "admin"
And I am on "Course 1" course homepage with editing mode on
And I add the "Activities" block
When I click on "H5P" "link" in the "Activities" "block"
Then I should see "An overview of all activities in the course"
And I should see "Name" in the "h5pactivity_overview_collapsible" "region"
And I should see "H5P type" in the "h5pactivity_overview_collapsible" "region"
And I should see "Actions" in the "h5pactivity_overview_collapsible" "region"
@@ -0,0 +1,247 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
namespace mod_h5pactivity\courseformat;
use core_courseformat\local\overview\overviewfactory;
/**
* Tests for H5P activity overview
*
* @covers \mod_h5pactivity\courseformat\overview
* @package mod_h5pactivity
* @category test
* @copyright 2025 Amaia Anabitarte <[email protected]>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
final class overview_test extends \advanced_testcase {
/**
* Test get_actions_overview.
*
* @covers ::get_actions_overview
*/
public function test_get_actions_overview(): void {
$this->resetAfterTest();
$this->setAdminUser();
$course = $this->getDataGenerator()->create_course();
$activity = $this->getDataGenerator()->create_module(
'h5pactivity',
['course' => $course, 'enabletracking' => 1],
);
$cm = get_fast_modinfo($course)->get_cm($activity->cmid);
// Prepare users: 1 teacher, 2 students, 1 unenroled user.
$teacher = $this->getDataGenerator()->create_and_enrol($course, 'editingteacher');
$student = $this->getDataGenerator()->create_and_enrol($course, 'student');
$generator = $this->getDataGenerator()->get_plugin_generator('mod_h5pactivity');
// Students have no action column.
$this->setUser($student);
$this->assertNull(overviewfactory::create($cm)->get_actions_overview());
// Teachers have a 'View results' button.
$this->setUser($teacher);
$items = overviewfactory::create($cm)->get_actions_overview();
$this->assertNotNull($items);
$this->assertEquals(get_string('actions'), $items->get_name());
}
/**
* Test get_extra_h5ptype_overview.
*
* @covers ::get_extra_h5ptype_overview
* @dataProvider provider_test_get_extra_h5type_overview
*
* @param string $h5pfile
* @param bool $iscorrect
* @param string $expected
* @return void
*/
public function test_get_extra_h5ptype_overview(
string $h5pfile,
bool $iscorrect,
string $expected
): void {
global $CFG;
$this->resetAfterTest();
$this->setAdminUser();
$course = $this->getDataGenerator()->create_course();
$params = [
'course' => $course->id,
'packagefilepath' => $CFG->dirroot.'/h5p/tests/fixtures/'.$h5pfile,
'introformat' => 1,
];
$activity = $this->getDataGenerator()->create_module('h5pactivity', $params);
// Add filename and contextid to make easier the asserts.
$activity->filename = $h5pfile;
$context = \context_module::instance($activity->cmid);
$activity->contextid = $context->id;
// Create a fake deploy H5P file.
/** @var \core_h5p_generator $h5pgenerator */
$h5pgenerator = $this->getDataGenerator()->get_plugin_generator('core_h5p');
if (!$iscorrect) {
$this->expectException(\TypeError::class);
}
$h5pgenerator->create_export_file($activity->filename, $context->id, 'mod_h5pactivity', 'package');
$teacher = $this->getDataGenerator()->create_and_enrol($course, 'editingteacher');
$this->setUser($teacher);
$cm = get_fast_modinfo($course)->get_cm($activity->cmid);
$items = overviewfactory::create($cm)->get_extra_overview_items();
$this->assertEquals($expected, $items['h5ptype']->get_value());
$student = $this->getDataGenerator()->create_and_enrol($course, 'student');
$this->setUser($student);
$cm = get_fast_modinfo($course)->get_cm($activity->cmid);
$items = overviewfactory::create($cm)->get_extra_overview_items();
$this->assertArrayNotHasKey('h5ptype', $items);
}
/**
* Data provider for test h5p type overview extra.
*
* @return array
*/
public static function provider_test_get_extra_h5type_overview(): array {
return [
'Basic package' => [
'h5pfile' => 'basic_essay.h5p',
'iscorrect' => true,
'expected' => 'Essay',
],
'No json file' => [
'h5pfile' => 'no-json-file.h5p',
'iscorrect' => false,
'expected' => get_string('unknowntype', 'mod_h5pactivity'),
],
'Unzippable package' => [
'h5pfile' => 'unzippable.h5p',
'iscorrect' => false,
'expected' => get_string('unknowntype', 'mod_h5pactivity'),
],
];
}
/**
* Test get_extra_overview_items.
*
* @covers ::get_extra_overview_items
*/
public function test_get_extra_attempts_overview(): void {
$this->resetAfterTest();
$this->setAdminUser();
$course = $this->getDataGenerator()->create_course();
$activity = $this->getDataGenerator()->create_module(
'h5pactivity',
['course' => $course, 'enabletracking' => 1],
);
$cm = get_fast_modinfo($course)->get_cm($activity->cmid);
// Prepare users: 1 teacher, 2 students, 1 unenroled user.
$teacher = $this->getDataGenerator()->create_and_enrol($course, 'editingteacher');
$student = $this->getDataGenerator()->create_and_enrol($course, 'student');
$other = $this->getDataGenerator()->create_and_enrol($course, 'student');
$generator = $this->getDataGenerator()->get_plugin_generator('mod_h5pactivity');
// No attempts yet.
$this->setUser($teacher);
$items = overviewfactory::create($cm)->get_extra_overview_items();
$this->assertEquals(0, $items['totalattempts']->get_value());
$this->setUser($student);
$items = overviewfactory::create($cm)->get_extra_overview_items();
$this->assertEquals(0, $items['myattempts']->get_value());
// Attempts done by other student.
$params = ['cmid' => $cm->id, 'userid' => $other->id];
$generator->create_content($activity, $params);
$generator->create_content($activity, $params);
$this->setUser($teacher);
$items = overviewfactory::create($cm)->get_extra_overview_items();
$this->assertEquals(2, $items['totalattempts']->get_value());
$this->setUser($student);
$items = overviewfactory::create($cm)->get_extra_overview_items();
$this->assertEquals(0, $items['myattempts']->get_value());
// Attempts done by the student.
$params = ['cmid' => $cm->id, 'userid' => $student->id];
$generator->create_content($activity, $params);
$generator->create_content($activity, $params);
$this->setUser($teacher);
$items = overviewfactory::create($cm)->get_extra_overview_items();
$this->assertEquals(4, $items['totalattempts']->get_value());
$this->setUser($student);
$items = overviewfactory::create($cm)->get_extra_overview_items();
$this->assertEquals(2, $items['myattempts']->get_value());
}
/**
* Test get_extra_studentsattempted_overview.
*
* @covers ::get_extra_studentsattempted_overview
*/
public function test_get_extra_studentsattempted_overview(): void {
$this->resetAfterTest();
$this->setAdminUser();
$course = $this->getDataGenerator()->create_course();
$activity = $this->getDataGenerator()->create_module(
'h5pactivity',
['course' => $course, 'enabletracking' => 1],
);
$cm = get_fast_modinfo($course)->get_cm($activity->cmid);
// Prepare users: 1 teacher, 2 students, 1 unenroled user.
$teacher = $this->getDataGenerator()->create_and_enrol($course, 'editingteacher');
$student = $this->getDataGenerator()->create_and_enrol($course, 'student');
$other = $this->getDataGenerator()->create_and_enrol($course, 'student');
$generator = $this->getDataGenerator()->get_plugin_generator('mod_h5pactivity');
// No attempts yet.
$this->setUser($teacher);
$items = overviewfactory::create($cm)->get_extra_overview_items();
$this->assertEquals(0, $items['attempted']->get_value());
$this->assertEquals('<strong>0</strong> of 2', $items['attempted']->get_content());
// With attempts.
$params = ['cmid' => $cm->id, 'userid' => $student->id];
$generator->create_content($activity, $params);
$generator->create_content($activity, $params);
$items = overviewfactory::create($cm)->get_extra_overview_items();
$this->assertEquals(1, $items['attempted']->get_value());
$this->assertEquals('<strong>1</strong> of 2', $items['attempted']->get_content());
}
}