2021-04-15 20:54:58 +00:00
|
|
|
<?php
|
|
|
|
|
|
|
|
|
|
namespace MediaWiki\Tests\User;
|
|
|
|
|
|
|
|
|
|
use DateTime;
|
|
|
|
|
use MediaWiki\User\UserTimeCorrection;
|
|
|
|
|
use MediaWikiUnitTestCase;
|
|
|
|
|
|
|
|
|
|
class UserTimeCorrectionTest extends MediaWikiUnitTestCase {
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @covers \MediaWiki\User\UserTimeCorrection::__construct
|
|
|
|
|
* @covers \MediaWiki\User\UserTimeCorrection::__toString
|
|
|
|
|
* @covers \MediaWiki\User\UserTimeCorrection::isValid
|
|
|
|
|
* @dataProvider provideTimeCorrectionExamples
|
|
|
|
|
*
|
|
|
|
|
* @param string $input
|
|
|
|
|
* @param string $expected
|
|
|
|
|
* @param bool $isValid
|
|
|
|
|
*/
|
|
|
|
|
public function testParser( $input, $expected, $isValid ) {
|
|
|
|
|
$value = new UserTimeCorrection( $input );
|
|
|
|
|
self::assertEquals( $expected, (string)$value );
|
|
|
|
|
self::assertEquals( $isValid, $value->isValid() );
|
|
|
|
|
}
|
|
|
|
|
|
2023-03-23 11:36:19 +00:00
|
|
|
public static function provideTimeCorrectionExamples() {
|
2021-04-15 20:54:58 +00:00
|
|
|
return [
|
|
|
|
|
[ '', 'System|0', false ],
|
|
|
|
|
[ 'bogus', 'System|0', false ],
|
|
|
|
|
[ 'ZoneInfo', 'Offset|0', false ],
|
|
|
|
|
[ 'ZoneInfo|bogus', 'Offset|0', false ],
|
|
|
|
|
[ 'ZoneInfo|120|Africa/Johannesburg|bogus', 'Offset|120', false ],
|
|
|
|
|
[ 'ZoneInfo|120|Unknown/Unknown', 'Offset|120', false ],
|
|
|
|
|
// Africa/Johannesburg has not DST
|
|
|
|
|
[ 'ZoneInfo|0|Africa/Johannesburg', 'ZoneInfo|120|Africa/Johannesburg', true ],
|
|
|
|
|
[ 'ZoneInfo|120|Africa/Johannesburg', 'ZoneInfo|120|Africa/Johannesburg', true ],
|
|
|
|
|
// Deprecated timezone name
|
|
|
|
|
[ 'ZoneInfo|330|Asia/Calcutta', 'ZoneInfo|330|Asia/Calcutta', true ],
|
|
|
|
|
// Timezone identifier with space in name
|
|
|
|
|
[ 'ZoneInfo|-420|America/Dawson_Creek', 'ZoneInfo|-420|America/Dawson_Creek', true ],
|
|
|
|
|
[ 'System', 'System|0', true ],
|
|
|
|
|
[ 'System|0', 'System|0', true ],
|
|
|
|
|
[ 'System|120', 'System|0', true ],
|
Use UserTimeCorrection in Language::userAdjust
There might be slight behaviour differences, particularly in case of
offsets that are > 14 or < -12, but I don't think it's really worth
special-casing that, since other parts of the code already limits
offsets to values in that interval.
Also fix a bug in UserTimeCorrection where ctype_digit wouldn't
recognize negative offsets specified only as an integer.
Also add a lot of tests for userAdjust, actually testing the parsing
logic, and not just the fallback to the local offset (which is what
**all** the previous test cases were doing). Ideally, this test would be
a unit test and be moved elsewhere, but I don't think it's worth doing
that now, since I assume the Language class will be refactored anyway at
some point.
Finally, use DateTime::modify instead of mktime. It's more readable, it
works the same, but is much more compact. It also means we don't have to
suppress any errors (which I think was already unnecessary, but still).
Bug: T322352
Change-Id: Ie0ccdb0c16aaa6ac888ca1e13008a8b214ac8994
2022-10-23 18:12:30 +00:00
|
|
|
// Back-compat formats
|
2021-04-15 20:54:58 +00:00
|
|
|
[ '2:30', 'Offset|150', true ],
|
|
|
|
|
[ '02:30', 'Offset|150', true ],
|
|
|
|
|
[ '+02:30', 'Offset|150', true ],
|
2022-10-08 15:49:54 +00:00
|
|
|
[ 'Offset|150', 'Offset|150', true ],
|
2021-04-15 20:54:58 +00:00
|
|
|
[ '0230', 'Offset|840', false ],
|
|
|
|
|
[ '2', 'Offset|120', true ],
|
Use UserTimeCorrection in Language::userAdjust
There might be slight behaviour differences, particularly in case of
offsets that are > 14 or < -12, but I don't think it's really worth
special-casing that, since other parts of the code already limits
offsets to values in that interval.
Also fix a bug in UserTimeCorrection where ctype_digit wouldn't
recognize negative offsets specified only as an integer.
Also add a lot of tests for userAdjust, actually testing the parsing
logic, and not just the fallback to the local offset (which is what
**all** the previous test cases were doing). Ideally, this test would be
a unit test and be moved elsewhere, but I don't think it's worth doing
that now, since I assume the Language class will be refactored anyway at
some point.
Finally, use DateTime::modify instead of mktime. It's more readable, it
works the same, but is much more compact. It also means we don't have to
suppress any errors (which I think was already unnecessary, but still).
Bug: T322352
Change-Id: Ie0ccdb0c16aaa6ac888ca1e13008a8b214ac8994
2022-10-23 18:12:30 +00:00
|
|
|
[ '-2', 'Offset|-120', true ],
|
2021-04-15 20:54:58 +00:00
|
|
|
[ '14:00', 'Offset|840', true ],
|
|
|
|
|
[ '-12:00', 'Offset|-720', true ],
|
|
|
|
|
[ '15:00', 'Offset|840', false ],
|
|
|
|
|
[ '-13:00', 'Offset|-720', false ],
|
2022-10-08 15:49:54 +00:00
|
|
|
[ 'Offset|900', 'Offset|840', false ],
|
|
|
|
|
[ 'Offset|-780', 'Offset|-720', false ],
|
2021-04-15 20:54:58 +00:00
|
|
|
[ '2:30:40', 'Offset|150', true ],
|
|
|
|
|
[ '2:30bogus', 'Offset|150', true ],
|
|
|
|
|
[ '2.50', 'System|0', false ],
|
|
|
|
|
[ 'UTC-8', 'System|0', false ],
|
|
|
|
|
];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
2022-06-02 12:07:15 +00:00
|
|
|
* @covers \MediaWiki\User\UserTimeCorrection::__construct
|
|
|
|
|
* @covers \MediaWiki\User\UserTimeCorrection::__toString
|
|
|
|
|
* @covers \MediaWiki\User\UserTimeCorrection::isValid
|
2021-04-15 20:54:58 +00:00
|
|
|
* @dataProvider provideServerTZoffsetExamples
|
|
|
|
|
*
|
|
|
|
|
* @param int $serverOffset
|
|
|
|
|
* @param string $input
|
|
|
|
|
* @param string $expected
|
|
|
|
|
* @param bool $isValid
|
|
|
|
|
*/
|
|
|
|
|
public function testServerOffset( int $serverOffset, string $input, string $expected, bool $isValid ) {
|
|
|
|
|
$value = new UserTimeCorrection( $input, null, $serverOffset );
|
|
|
|
|
self::assertEquals( $expected, (string)$value );
|
|
|
|
|
self::assertEquals( $isValid, $value->isValid() );
|
|
|
|
|
}
|
|
|
|
|
|
2023-03-23 11:36:19 +00:00
|
|
|
public static function provideServerTZoffsetExamples() {
|
2021-04-15 20:54:58 +00:00
|
|
|
return [
|
|
|
|
|
[ 120, '', 'System|120', false ],
|
|
|
|
|
[ 120, 'bogus', 'System|120', false ],
|
|
|
|
|
[ 120, 'System', 'System|120', true ],
|
|
|
|
|
[ 120, 'System|120', 'System|120', true ],
|
|
|
|
|
[ -120, 'System|-120', 'System|-120', true ],
|
|
|
|
|
[ 840, 'System|840', 'System|840', true ],
|
|
|
|
|
];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @covers \MediaWiki\User\UserTimeCorrection::__construct
|
|
|
|
|
* @covers \MediaWiki\User\UserTimeCorrection::__toString
|
|
|
|
|
* @covers \MediaWiki\User\UserTimeCorrection::isValid
|
|
|
|
|
* @dataProvider provideDSTVariations
|
|
|
|
|
*
|
|
|
|
|
* @param DateTime $date Date/time to which the correction would apply
|
|
|
|
|
* @param string $input
|
|
|
|
|
* @param string $expected
|
|
|
|
|
* @param bool $isValid
|
|
|
|
|
*/
|
2022-06-02 12:07:15 +00:00
|
|
|
public function testDSTVariations( DateTime $date, $input, $expected, $isValid ) {
|
2021-04-15 20:54:58 +00:00
|
|
|
$value = new UserTimeCorrection( $input, $date );
|
|
|
|
|
self::assertEquals( $expected, (string)$value );
|
|
|
|
|
self::assertEquals( $isValid, $value->isValid() );
|
|
|
|
|
}
|
|
|
|
|
|
2023-03-23 11:36:19 +00:00
|
|
|
public static function provideDSTVariations() {
|
2021-04-15 20:54:58 +00:00
|
|
|
// Amsterdam observes DST. Johannesburg does not
|
|
|
|
|
return [
|
|
|
|
|
[ new DateTime( '2020-12-01' ), 'ZoneInfo|60|Europe/Amsterdam', 'ZoneInfo|60|Europe/Amsterdam', true ],
|
|
|
|
|
[ new DateTime( '2020-12-01' ), 'ZoneInfo|120|Europe/Amsterdam', 'ZoneInfo|60|Europe/Amsterdam', true ],
|
|
|
|
|
[ new DateTime( '2020-12-01' ), 'ZoneInfo|120|Africa/Johannesburg', 'ZoneInfo|120|Africa/Johannesburg', true ],
|
|
|
|
|
[ new DateTime( '2020-06-01' ), 'ZoneInfo|60|Europe/Amsterdam', 'ZoneInfo|120|Europe/Amsterdam', true ],
|
|
|
|
|
[ new DateTime( '2020-06-01' ), 'ZoneInfo|120|Europe/Amsterdam', 'ZoneInfo|120|Europe/Amsterdam', true ],
|
|
|
|
|
[ new DateTime( '2020-06-01' ), 'ZoneInfo|120|Africa/Johannesburg', 'ZoneInfo|120|Africa/Johannesburg', true ],
|
|
|
|
|
];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @covers \MediaWiki\User\UserTimeCorrection::getTimeOffset
|
|
|
|
|
* @covers \MediaWiki\User\UserTimeCorrection::getTimeOffsetInterval
|
|
|
|
|
* @covers \MediaWiki\User\UserTimeCorrection::getTimeZone
|
|
|
|
|
*/
|
|
|
|
|
public function testAccessors(): void {
|
|
|
|
|
$value = new UserTimeCorrection( 'ZoneInfo|120|Africa/Johannesburg' );
|
|
|
|
|
self::assertEquals( 120, $value->getTimeOffset() );
|
|
|
|
|
self::assertEquals( 120, (int)$value->getTimeOffsetInterval()->format( '%i' ) );
|
|
|
|
|
self::assertEquals( 'Africa/Johannesburg', $value->getTimeZone()->getName() );
|
|
|
|
|
}
|
2022-09-23 22:17:43 +00:00
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @param int $offset
|
|
|
|
|
* @param string $expected
|
|
|
|
|
* @dataProvider provideTimezoneOffsets
|
|
|
|
|
* @covers \MediaWiki\User\UserTimeCorrection::formatTimezoneOffset
|
|
|
|
|
*/
|
|
|
|
|
public function testFormatTimezoneOffset( int $offset, string $expected ) {
|
|
|
|
|
$this->assertSame( $expected, UserTimeCorrection::formatTimezoneOffset( $offset ) );
|
|
|
|
|
}
|
|
|
|
|
|
2023-03-23 11:36:19 +00:00
|
|
|
public static function provideTimezoneOffsets(): array {
|
2022-09-23 22:17:43 +00:00
|
|
|
return [
|
|
|
|
|
'00:00' => [ 0, '+00:00' ],
|
|
|
|
|
'Positive' => [ 120, '+02:00' ],
|
|
|
|
|
'Positive with minutes' => [ 150, '+02:30' ],
|
|
|
|
|
'Negative' => [ -120, '-02:00' ],
|
|
|
|
|
'Negative with minutes' => [ -150, '-02:30' ],
|
|
|
|
|
];
|
|
|
|
|
}
|
2021-04-15 20:54:58 +00:00
|
|
|
}
|