MDL-83889 mod_bigbluebuttonbn: Add date classes and tests
This commit is contained in:
@@ -0,0 +1,5 @@
|
||||
issueNumber: MDL-83889
|
||||
notes:
|
||||
mod_bigbluebuttonbn:
|
||||
- message: Add activity_dates class to BigblueButton module.
|
||||
type: improved
|
||||
@@ -0,0 +1,116 @@
|
||||
<?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/>.
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace mod_bigbluebuttonbn;
|
||||
|
||||
use cm_info;
|
||||
use core\activity_dates;
|
||||
|
||||
/**
|
||||
* Class for fetching the important dates in mod_bigbluebuttonbn for a given module instance and a user.
|
||||
*
|
||||
* @package mod_bigbluebuttonbn
|
||||
* @copyright 2025 Laurent David <[email protected]>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
class dates extends activity_dates {
|
||||
/**
|
||||
* Returns the activity due date.
|
||||
*
|
||||
* @var int|null $timeclose the activity due date
|
||||
*/
|
||||
protected ?int $timeclose = null;
|
||||
/**
|
||||
* @var int|null $timeopen the activity open date
|
||||
*/
|
||||
protected ?int $timeopen = null;
|
||||
|
||||
/**
|
||||
* @var instance the instance of the activity
|
||||
*/
|
||||
protected instance $instance;
|
||||
|
||||
/**
|
||||
* activity_dates constructor.
|
||||
*
|
||||
* @param cm_info $cm course module
|
||||
* @param int $userid user id
|
||||
*/
|
||||
public function __construct(cm_info $cm, int $userid) {
|
||||
parent::__construct($cm, $userid);
|
||||
$this->instance = instance::get_from_cmid((int) $cm->id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a list of important dates in mod_choice
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected function get_dates(): array {
|
||||
$timeopen = $this->instance->get_instance_var('openingtime');
|
||||
$timeclose = $this->instance->get_instance_var('closingtime');
|
||||
$now = time();
|
||||
$dates = [];
|
||||
|
||||
if ($timeopen) {
|
||||
$openlabelid = $timeopen > $now ? 'activitydate:opens' : 'activitydate:opened';
|
||||
$dates[] = [
|
||||
'dataid' => 'timeopen',
|
||||
'label' => get_string($openlabelid, 'course'),
|
||||
'timestamp' => (int) $timeopen,
|
||||
];
|
||||
$this->timeopen = (int) $timeopen;
|
||||
}
|
||||
|
||||
if ($timeclose) {
|
||||
$closelabelid = $timeclose > $now ? 'activitydate:closes' : 'activitydate:closed';
|
||||
$dates[] = [
|
||||
'dataid' => 'timeclose',
|
||||
'label' => get_string($closelabelid, 'course'),
|
||||
'timestamp' => (int) $timeclose,
|
||||
];
|
||||
$this->timeclose = (int) $timeclose;
|
||||
}
|
||||
|
||||
return $dates;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the activity due date.
|
||||
*
|
||||
* @return int|null
|
||||
*/
|
||||
public function get_close_date(): ?int {
|
||||
if (!isset($this->timeclose)) {
|
||||
$this->get_dates();
|
||||
}
|
||||
return $this->timeclose;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the activity open date.
|
||||
*
|
||||
* @return int|null
|
||||
*/
|
||||
public function get_open_date(): ?int {
|
||||
if (!isset($this->timeopen)) {
|
||||
$this->get_dates();
|
||||
}
|
||||
return $this->timeopen;
|
||||
}
|
||||
}
|
||||
@@ -40,25 +40,6 @@
|
||||
<span>{{#userdate}} {{startedat}}, {{#str}} strftimetime, core_langconfig{{/str}} {{/userdate}}.</span>
|
||||
<span class="status-message">{{statusmessage}}</span>
|
||||
</div>
|
||||
{{/statusrunning}}
|
||||
{{^statusrunning}}
|
||||
<div class="status-message">{{statusmessage}}</div>
|
||||
{{/statusrunning}}
|
||||
<div class="conf-opening-time">
|
||||
{{#openingtime}}
|
||||
<span class="conf-opening">
|
||||
<span class="fw-bold">{{#str}}mod_form_field_openingtime, bigbluebuttonbn{{/str}}:</span>
|
||||
{{#userdate}} {{.}}, {{#str}} strftimedaydatetime, langconfig {{/str}} {{/userdate}}
|
||||
</span>
|
||||
{{/openingtime}}
|
||||
{{#closingtime}}
|
||||
<div class="conf-closing">
|
||||
<span class="fw-bold">{{#str}}mod_form_field_closingtime, bigbluebuttonbn{{/str}}:</span>
|
||||
{{#userdate}} {{.}}, {{#str}} strftimedaydatetime, langconfig {{/str}} {{/userdate}}
|
||||
</div>
|
||||
{{/closingtime}}
|
||||
</div>
|
||||
{{#statusrunning}}
|
||||
<div>
|
||||
<span class="fw-bold">
|
||||
{{#moderatorplural}}{{#str}}view_message_moderators, mod_bigbluebuttonbn{{/str}}{{/moderatorplural}}
|
||||
@@ -74,6 +55,9 @@
|
||||
<span>{{participantcount}}</span>
|
||||
</div>
|
||||
{{/statusrunning}}
|
||||
{{^statusrunning}}
|
||||
<div class="status-message">{{statusmessage}}</div>
|
||||
{{/statusrunning}}
|
||||
</div>
|
||||
|
||||
<div id="bigbluebuttonbn-room-view-control-panel" data-bbb-id="{{bigbluebuttonbnid}}" class="mt-2">
|
||||
|
||||
+6
-6
@@ -28,9 +28,9 @@ Feature: Manage BigBlueButton session timings
|
||||
| C1 | bigbluebuttonbn | BBB 1 | <openingtime> | <closingtime> |
|
||||
When I am on the "BBB 1" "bigbluebuttonbn activity" page logged in as student1
|
||||
And "Join session" "link" <buttonvisibility> exist
|
||||
And I should see "Open:"
|
||||
And I should see "<opens>:"
|
||||
And I should see "<openingtime>%A, %d %B %Y##"
|
||||
And I should see "Close:"
|
||||
And I should see "<closes>:"
|
||||
And I should see "<closingtime>%A, %d %B %Y##"
|
||||
And I am viewing calendar in "month" view
|
||||
And I <calendarvisibility> see "BBB 1"
|
||||
@@ -39,7 +39,7 @@ Feature: Manage BigBlueButton session timings
|
||||
And I <upcomingeventvisibility> see "BBB 1" in the "Upcoming events" "block"
|
||||
|
||||
Examples:
|
||||
| openingtime | closingtime | calendarvisibility | buttonvisibility | upcomingeventvisibility |
|
||||
| ##now +1 minute## | ##now +5 minutes## | should | should not | should |
|
||||
| ##1 hour ago## | ##+2 hours## | should | should | should not |
|
||||
| ##yesterday## | ##yesterday +3 hours## | should not | should not | should not |
|
||||
| opens | closes | openingtime | closingtime | calendarvisibility | buttonvisibility | upcomingeventvisibility |
|
||||
| Opens | Closes | ##now +1 minute## | ##now +5 minutes## | should | should not | should |
|
||||
| Opened | Closes | ##1 hour ago## | ##+2 hours## | should | should | should not |
|
||||
| Opened | Closed | ##yesterday## | ##yesterday +3 hours## | should not | should not | should not |
|
||||
|
||||
@@ -0,0 +1,217 @@
|
||||
<?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/>.
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace mod_bigbluebuttonbn;
|
||||
|
||||
use advanced_testcase;
|
||||
use core\activity_dates;
|
||||
|
||||
/**
|
||||
* Class for unit testing mod_bigbluebutton\dates.
|
||||
*
|
||||
* @package mod_bigbluebuttonbn
|
||||
* @copyright 2025 Laurent David <[email protected]>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
* @coversDefaultClass \mod_bigbluebuttonbn\dates
|
||||
*/
|
||||
final class dates_test extends advanced_testcase {
|
||||
use \mod_bigbluebuttonbn\test\testcase_helper_trait;
|
||||
|
||||
/**
|
||||
* Data provider for get_dates_for_module().
|
||||
*
|
||||
* @return array[]
|
||||
*/
|
||||
public static function get_dates_for_module_provider(): array {
|
||||
$clock = \core\di::get(\core\clock::class);
|
||||
$now = $clock->time();
|
||||
$open = $now - DAYSECS;
|
||||
$close = $now + DAYSECS;
|
||||
|
||||
return [
|
||||
'Without any dates' => [
|
||||
null, null, [],
|
||||
],
|
||||
'Only with opening time' => [
|
||||
$open,
|
||||
null,
|
||||
[
|
||||
[
|
||||
'label' => get_string('activitydate:opened', 'course'),
|
||||
'timestamp' => $open,
|
||||
'dataid' => 'timeopen',
|
||||
],
|
||||
],
|
||||
],
|
||||
'Only with closing time' => [
|
||||
null,
|
||||
$close,
|
||||
[
|
||||
[
|
||||
'label' => get_string('activitydate:closes', 'course'),
|
||||
'timestamp' => $close,
|
||||
'dataid' => 'timeclose',
|
||||
],
|
||||
],
|
||||
],
|
||||
'With both times' => [
|
||||
$open,
|
||||
$close,
|
||||
[
|
||||
[
|
||||
'label' => get_string('activitydate:opened', 'course'),
|
||||
'timestamp' => $open,
|
||||
'dataid' => 'timeopen',
|
||||
],
|
||||
[
|
||||
'label' => get_string('activitydate:closes', 'course'),
|
||||
'timestamp' => $close,
|
||||
'dataid' => 'timeclose',
|
||||
],
|
||||
],
|
||||
],
|
||||
'With both times in the future' => [
|
||||
$now + DAYSECS,
|
||||
$now + (2 * DAYSECS),
|
||||
[
|
||||
[
|
||||
'label' => get_string('activitydate:opens', 'course'),
|
||||
'timestamp' => $now + DAYSECS,
|
||||
'dataid' => 'timeopen',
|
||||
],
|
||||
[
|
||||
'label' => get_string('activitydate:closes', 'course'),
|
||||
'timestamp' => $now + (2 * DAYSECS),
|
||||
'dataid' => 'timeclose',
|
||||
],
|
||||
],
|
||||
],
|
||||
'With both times in the past' => [
|
||||
$now - (2 * DAYSECS),
|
||||
$now - DAYSECS,
|
||||
[
|
||||
[
|
||||
'label' => get_string('activitydate:opened', 'course'),
|
||||
'timestamp' => $now - (2 * DAYSECS),
|
||||
'dataid' => 'timeopen',
|
||||
],
|
||||
[
|
||||
'label' => get_string('activitydate:closed', 'course'),
|
||||
'timestamp' => $now - DAYSECS,
|
||||
'dataid' => 'timeclose',
|
||||
],
|
||||
],
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Test for get_dates_for_module().
|
||||
*
|
||||
* @param int|null $open Opening time in the BigBlueButton.
|
||||
* @param int|null $close Closing time in the BigBlueButton.
|
||||
* @param array $expected The expected value of calling get_dates_for_module()
|
||||
* @covers ::get_dates_for_module
|
||||
* @dataProvider get_dates_for_module_provider
|
||||
*/
|
||||
public function test_get_dates_for_module(
|
||||
?int $open,
|
||||
?int $close,
|
||||
array $expected
|
||||
): void {
|
||||
$this->resetAfterTest();
|
||||
['user' => $user, 'cm' => $cm] = $this->setup_instance($open, $close);
|
||||
$this->setUser($user);
|
||||
$dates = activity_dates::get_dates_for_module($cm, (int) $user->id);
|
||||
|
||||
$this->assertEquals($expected, $dates);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Test for get_open_date().
|
||||
*
|
||||
* @param int|null $open Opening time in the BigBlueButton.
|
||||
* @param int|null $close Closing time in the BigBlueButton.
|
||||
* @covers ::get_open_date
|
||||
* @dataProvider get_dates_for_module_provider
|
||||
*/
|
||||
public function test_get_open_date(
|
||||
?int $open,
|
||||
?int $close,
|
||||
): void {
|
||||
|
||||
$this->resetAfterTest();
|
||||
['user' => $user, 'cm' => $cm] = $this->setup_instance($open, $close);
|
||||
$this->setUser($user);
|
||||
$dates = new \mod_bigbluebuttonbn\dates($cm, (int) $user->id);
|
||||
|
||||
$this->assertEquals($open, $dates->get_open_date());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test for get_close_date().
|
||||
*
|
||||
* @param int|null $open Opening time in the BigBlueButton.
|
||||
* @param int|null $close Closing time in the BigBlueButton.
|
||||
* @covers ::get_close_date
|
||||
* @dataProvider get_dates_for_module_provider
|
||||
*/
|
||||
public function test_get_close_date(
|
||||
?int $open,
|
||||
?int $close,
|
||||
): void {
|
||||
|
||||
$this->resetAfterTest();
|
||||
['user' => $user, 'cm' => $cm] = $this->setup_instance($open, $close);
|
||||
$dates = new \mod_bigbluebuttonbn\dates($cm, (int) $user->id);
|
||||
|
||||
$this->assertEquals($close, $dates->get_close_date());
|
||||
}
|
||||
|
||||
/**
|
||||
* Setup a BigBlueButton activity instance.
|
||||
*
|
||||
* @param int|null $open Opening time in the BigBlueButton.
|
||||
* @param int|null $close Closing time in the BigBlueButton.
|
||||
* @return array with keys 'user' and 'cm'.
|
||||
*/
|
||||
private function setup_instance(
|
||||
?int $open,
|
||||
?int $close,
|
||||
): array {
|
||||
$generator = $this->getDataGenerator();
|
||||
|
||||
$course = $generator->create_course();
|
||||
$user = $generator->create_user();
|
||||
$generator->enrol_user($user->id, $course->id);
|
||||
$data = [];
|
||||
if ($open !== null) {
|
||||
$data['openingtime'] = $open;
|
||||
}
|
||||
if ($close !== null) {
|
||||
$data['closingtime'] = $close;
|
||||
}
|
||||
$this->setAdminUser();
|
||||
[$bbactivitycontext, $bbactivitycm, $bbactivity] = $this->create_instance(
|
||||
$course,
|
||||
$data
|
||||
);
|
||||
return ['user' => $user, 'cm' => $bbactivitycm];
|
||||
}
|
||||
}
|
||||
@@ -69,11 +69,27 @@ class mod_bigbluebuttonbn_generator extends \testing_module_generator {
|
||||
"recordings_preview" => 0,
|
||||
"grade" => 0,
|
||||
];
|
||||
|
||||
$record = (array) $record;
|
||||
|
||||
$record['participants'] = json_encode($this->get_participants_from_record($record));
|
||||
|
||||
if (!empty($record['openingtime'])) {
|
||||
if (is_numeric($record['openingtime'])) {
|
||||
$record['openingtime'] = intval($record['openingtime']);
|
||||
} else {
|
||||
// If it is a string, we assume it is a timestamp.
|
||||
$record['openingtime'] = strtotime($record['openingtime']);
|
||||
}
|
||||
}
|
||||
if (!empty($record['closingtime'])) {
|
||||
if (is_numeric($record['closingtime'])) {
|
||||
$record['closingtime'] = intval($record['closingtime']);
|
||||
} else {
|
||||
// If it is a string, we assume it is a timestamp.
|
||||
$record['closingtime'] = strtotime($record['closingtime']);
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($defaults as $key => $value) {
|
||||
if (!isset($record[$key])) {
|
||||
$record[$key] = $value;
|
||||
|
||||
@@ -0,0 +1,105 @@
|
||||
<?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_bigbluebuttonbn;
|
||||
|
||||
/**
|
||||
* Genarator tests class for mod_bigbluebuttonbn.
|
||||
*
|
||||
* @package mod_bigbluebuttonbn
|
||||
* @category test
|
||||
* @copyright 2025 Laurent David <[email protected]>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
final class generator_test extends \advanced_testcase {
|
||||
/**
|
||||
* Test the creation of a bigbluebuttonbn instance.
|
||||
* @covers \mod_bigbluebuttonbn_generator::create_instance
|
||||
*/
|
||||
public function test_create_instance(): void {
|
||||
$db = \core\di::get(\moodle_database::class);
|
||||
$this->resetAfterTest();
|
||||
$this->setAdminUser();
|
||||
|
||||
$course = $this->getDataGenerator()->create_course();
|
||||
$bigbluebuttonbn = $this->getDataGenerator()->create_module('bigbluebuttonbn', ['course' => $course]);
|
||||
$records = $db->get_records('bigbluebuttonbn', ['course' => $course->id], 'id');
|
||||
$this->assertEquals(1, count($records));
|
||||
$this->assertTrue(array_key_exists($bigbluebuttonbn->id, $records));
|
||||
|
||||
$params = ['course' => $course->id, 'name' => 'Another bigbluebuttonbn'];
|
||||
$bigbluebuttonbn = $this->getDataGenerator()->create_module('bigbluebuttonbn', $params);
|
||||
$records = $db->get_records('bigbluebuttonbn', ['course' => $course->id], 'id');
|
||||
$this->assertEquals(2, count($records));
|
||||
$this->assertEquals('Another bigbluebuttonbn', $records[$bigbluebuttonbn->id]->name);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Test the creation of a bigbluebuttonbn instance with a custom name.
|
||||
*
|
||||
* @param string|int $opening The opening time as a timestamp or human-readable date.
|
||||
* @param string|int $closing The closing time as a timestamp or human-readable date
|
||||
* @param int $expectedopening The expected opening time as a timestamp.
|
||||
* @param int $expectedclosing The expected closing time as a timestamp.
|
||||
* @covers \mod_bigbluebuttonbn_generator::create_instance
|
||||
* @dataProvider provider_create_instance_with_name
|
||||
*/
|
||||
public function test_create_instance_with_dates(
|
||||
string|int $opening,
|
||||
string|int $closing,
|
||||
int $expectedopening,
|
||||
int $expectedclosing
|
||||
): void {
|
||||
$this->resetAfterTest();
|
||||
$this->setAdminUser();
|
||||
|
||||
$course = $this->getDataGenerator()->create_course();
|
||||
$params = ['course' => $course->id, 'openingtime' => $opening, 'closingtime' => $closing];
|
||||
$bigbluebuttonbn = $this->getDataGenerator()->create_module('bigbluebuttonbn', $params);
|
||||
$instance = \mod_bigbluebuttonbn\instance::get_from_instanceid($bigbluebuttonbn->id);
|
||||
$this->assertEquals($expectedopening, $instance->get_instance_var('openingtime'));
|
||||
$this->assertEquals($expectedclosing, $instance->get_instance_var('closingtime'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Data provider for test_create_instance_with_dates.
|
||||
*
|
||||
* @return array[]
|
||||
*/
|
||||
public static function provider_create_instance_with_name(): array {
|
||||
global $CFG;
|
||||
require_once($CFG->libdir . '/testing/classes/frozen_clock.php');
|
||||
$clock = new \frozen_clock();
|
||||
\core\di::set(\core\clock::class, $clock);
|
||||
$opening = $clock->time();
|
||||
$closing = $opening + DAYSECS;
|
||||
return [
|
||||
'Timestamp' => [
|
||||
$opening,
|
||||
$closing,
|
||||
$opening,
|
||||
$closing,
|
||||
],
|
||||
'Human date' => [
|
||||
userdate($opening, get_string('strftimedatetimeaccurate', 'langconfig')),
|
||||
userdate($closing, get_string('strftimedatetimeaccurate', 'langconfig')),
|
||||
$opening,
|
||||
$closing,
|
||||
],
|
||||
];
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user