mirror of
https://github.com/moodle/moodle.git
synced 2025-02-19 23:55:54 +01:00
MDL-83316 Behat: New step allows system clock change
This commit is contained in:
parent
acff633e39
commit
d4564b876e
61
admin/tool/behat/tests/behat/frozen_clock.feature
Normal file
61
admin/tool/behat/tests/behat/frozen_clock.feature
Normal file
@ -0,0 +1,61 @@
|
||||
@tool @tool_behat
|
||||
Feature: Frozen clock in Behat
|
||||
In order to write tests that depend on the current system time
|
||||
As a test writer
|
||||
I need to set the time using a Behat step
|
||||
|
||||
Background:
|
||||
Given the following "courses" exist:
|
||||
| fullname | shortname |
|
||||
| Course 1 | C1 |
|
||||
And the following "activities" exist:
|
||||
| activity | course | name | idnumber | externalurl |
|
||||
| url | C1 | Fixture | url1 | #wwwroot#/admin/tool/behat/tests/fixtures/core/showtime.php |
|
||||
| forum | C1 | TestForum | forum1 | |
|
||||
|
||||
Scenario: Time has been frozen
|
||||
# Set up 2 forum discussions at different times. This tests the clock in the Behat CLI process.
|
||||
Given the time is frozen at "2024-03-01 12:34:56"
|
||||
And the following "mod_forum > discussions" exist:
|
||||
| user | forum | name | message |
|
||||
| admin | forum1 | Subject1 | Message1 |
|
||||
And the time is frozen at "2024-08-01 12:34:56"
|
||||
And the following "mod_forum > discussions" exist:
|
||||
| user | forum | name | message |
|
||||
| admin | forum1 | Subject2 | Message2 |
|
||||
When I am on the "TestForum" "forum activity" page logged in as admin
|
||||
Then I should see "1 Mar 2024" in the "Subject1" "table_row"
|
||||
And I should see "1 Aug 2024" in the "Subject2" "table_row"
|
||||
# Also view time on the fixture page. This tests the clock for Behat web server requests.
|
||||
And I am on the "Fixture" "url activity" page
|
||||
And I should see "Behat time is not the same as real time"
|
||||
# This Unix time corresponds to 12:34:56 in Perth time zone.
|
||||
And I should see "Unix time 1722486896"
|
||||
And I should see "Date-time 2024-08-01 12:34:56"
|
||||
|
||||
# This scenario is second, to verify that the clock automatically goes back to normal after test.
|
||||
Scenario: Time is normal
|
||||
Given the following "mod_forum > discussions" exist:
|
||||
| user | forum | name | message |
|
||||
| admin | forum1 | Subject1 | Message1 |
|
||||
When I am on the "TestForum" "forum activity" page logged in as admin
|
||||
# The time should be the real current time, not the frozen time.
|
||||
Then I should see "## today ##%d %b %Y##" in the "Subject1" "table_row"
|
||||
And I am on the "Fixture" "url activity" page
|
||||
And I should see "Behat time is the same as real time"
|
||||
|
||||
Scenario: Time is frozen and then unfrozen
|
||||
Given the time is frozen at "2024-03-01 12:34:56"
|
||||
And the following "mod_forum > discussions" exist:
|
||||
| user | forum | name | message |
|
||||
| admin | forum1 | Subject1 | Message1 |
|
||||
And the time is no longer frozen
|
||||
And the following "mod_forum > discussions" exist:
|
||||
| user | forum | name | message |
|
||||
| admin | forum1 | Subject2 | Message2 |
|
||||
When I am on the "TestForum" "forum activity" page logged in as admin
|
||||
Then I should see "1 Mar 2024" in the "Subject1" "table_row"
|
||||
# The time should be the real current time, not the frozen time for this entry.
|
||||
Then I should see "## today ##%d %b %Y##" in the "Subject2" "table_row"
|
||||
And I am on the "Fixture" "url activity" page
|
||||
And I should see "Behat time is the same as real time"
|
52
admin/tool/behat/tests/fixtures/core/showtime.php
vendored
Normal file
52
admin/tool/behat/tests/fixtures/core/showtime.php
vendored
Normal file
@ -0,0 +1,52 @@
|
||||
<?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/>.
|
||||
|
||||
/**
|
||||
* Fixture to show the current server time using \core\clock.
|
||||
*
|
||||
* @package tool_behat
|
||||
* @copyright 2024 The Open University
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
// phpcs:disable moodle.Files.RequireLogin.Missing
|
||||
require(__DIR__ . '/../../../../../../config.php');
|
||||
|
||||
defined('BEHAT_SITE_RUNNING') || die('Behat fixture');
|
||||
|
||||
$PAGE->set_context(\context_system::instance());
|
||||
$PAGE->set_url(new \moodle_url('/admin/tool/behat/tests/fixtures/core/showtime.php'));
|
||||
|
||||
echo $OUTPUT->header();
|
||||
|
||||
$clock = \core\di::get(\core\clock::class);
|
||||
$dt = $clock->now();
|
||||
$realbefore = time();
|
||||
$time = $clock->time();
|
||||
$realafter = time();
|
||||
|
||||
echo html_writer::div('Unix time ' . $time);
|
||||
echo html_writer::div('Date-time ' . $dt->format('Y-m-d H:i:s'));
|
||||
|
||||
echo html_writer::div('TZ ' . $dt->getTimezone()->getName());
|
||||
|
||||
if ($time >= $realbefore && $time <= $realafter) {
|
||||
echo html_writer::div('Behat time is the same as real time');
|
||||
} else {
|
||||
echo html_writer::div('Behat time is not the same as real time');
|
||||
}
|
||||
|
||||
echo $OUTPUT->footer();
|
@ -120,7 +120,16 @@ class di {
|
||||
|
||||
// The Moodle Clock implementation, which itself is an extension of PSR-20.
|
||||
// Alias the PSR-20 clock interface to the Moodle clock. They are compatible.
|
||||
\core\clock::class => fn() => new \core\system_clock(),
|
||||
\core\clock::class => function () {
|
||||
global $CFG;
|
||||
|
||||
// Web requests to the Behat site can use a frozen clock if configured.
|
||||
if (defined('BEHAT_SITE_RUNNING') && !empty($CFG->behat_frozen_clock)) {
|
||||
require_once($CFG->libdir . '/testing/classes/frozen_clock.php');
|
||||
return new \frozen_clock((int)$CFG->behat_frozen_clock);
|
||||
}
|
||||
return new \core\system_clock();
|
||||
},
|
||||
\Psr\Clock\ClockInterface::class => \DI\get(\core\clock::class),
|
||||
|
||||
// Note: libphonenumber PhoneNumberUtil uses a singleton.
|
||||
|
@ -35,7 +35,10 @@ class frozen_clock implements \core\clock {
|
||||
?int $time = null,
|
||||
) {
|
||||
if ($time) {
|
||||
$this->time = new \DateTimeImmutable("@{$time}");
|
||||
// Note that the constructor with time zone does not work when specifying a timestamp,
|
||||
// so we have to set timezone separately afterward.
|
||||
$this->time = (new \DateTimeImmutable("@{$time}"))
|
||||
->setTimezone(\core_date::get_server_timezone_object());
|
||||
} else {
|
||||
$this->time = new \DateTimeImmutable();
|
||||
}
|
||||
@ -55,7 +58,8 @@ class frozen_clock implements \core\clock {
|
||||
* @param int $time
|
||||
*/
|
||||
public function set_to(int $time): void {
|
||||
$this->time = new \DateTimeImmutable("@{$time}");
|
||||
$this->time = (new \DateTimeImmutable("@{$time}"))
|
||||
->setTimezone(\core_date::get_server_timezone_object());
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -2708,4 +2708,34 @@ EOF;
|
||||
throw new Exception("Text '{$text}' found in the row containing '{$rowtext}'");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the current time for the remainder of this Behat test.
|
||||
*
|
||||
* This is not supported everywhere in Moodle: if code uses \core\clock through DI then
|
||||
* it will work, but if it just calls time() it will still get the real time.
|
||||
*
|
||||
* @Given the time is frozen at :datetime
|
||||
* @param string $datetime Date and time in a format that strtotime understands
|
||||
*/
|
||||
public function the_time_is_frozen_at(string $datetime): void {
|
||||
global $CFG;
|
||||
require_once($CFG->libdir . '/testing/classes/frozen_clock.php');
|
||||
|
||||
$timestamp = strtotime($datetime);
|
||||
// The config variable is used to set up a frozen clock in each Behat web request.
|
||||
set_config('behat_frozen_clock', $timestamp);
|
||||
// Simply setting a frozen clock in DI should work for future steps in Behat CLI process.
|
||||
\core\di::set(\core\clock::class, new \frozen_clock($timestamp));
|
||||
}
|
||||
|
||||
/**
|
||||
* Stops freezing time so that it goes back to real time.
|
||||
*
|
||||
* @Given the time is no longer frozen
|
||||
*/
|
||||
public function the_time_is_no_longer_frozen(): void {
|
||||
unset_config('behat_frozen_clock');
|
||||
\core\di::set(\core\clock::class, new \core\system_clock());
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user