wiki.techinc.nl/tests/phpunit/unit/includes/user/UserTimeCorrectionTest.php
Daimona Eaytoy b6431b5caf Fix logic for formatting negative timezone offsets
As described on the task, floor() returns the closest integer to the
left, and so it's not the right choice in this case for negative
offsets.

Put the logic in a static method of the UserTimeCorrection class so that
it can be reused elsewhere without making the previous mistake, and add
tests for it.

Also update a comment in UserTimeCorrection, as a follow-up to
I99a00dff7e3319ce45883191daee16bec1ed68ba.

Bug: T318455
Change-Id: I9acc8fa278d5a58a1d56c28c9e8b3f9093f8add9
2022-09-23 22:35:11 +00:00

149 lines
5.5 KiB
PHP

<?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() );
}
public function provideTimeCorrectionExamples() {
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 ],
[ '2:30', 'Offset|150', true ],
[ '02:30', 'Offset|150', true ],
[ '+02:30', 'Offset|150', true ],
[ '0230', 'Offset|840', false ],
[ '2', 'Offset|120', true ],
[ '14:00', 'Offset|840', true ],
[ '-12:00', 'Offset|-720', true ],
[ '15:00', 'Offset|840', false ],
[ '-13:00', 'Offset|-720', false ],
[ '2:30:40', 'Offset|150', true ],
[ '2:30bogus', 'Offset|150', true ],
[ '2.50', 'System|0', false ],
[ 'UTC-8', 'System|0', false ],
];
}
/**
* @covers \MediaWiki\User\UserTimeCorrection::__construct
* @covers \MediaWiki\User\UserTimeCorrection::__toString
* @covers \MediaWiki\User\UserTimeCorrection::isValid
* @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() );
}
public function provideServerTZoffsetExamples() {
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
*/
public function testDSTVariations( DateTime $date, $input, $expected, $isValid ) {
$value = new UserTimeCorrection( $input, $date );
self::assertEquals( $expected, (string)$value );
self::assertEquals( $isValid, $value->isValid() );
}
public function provideDSTVariations() {
// 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() );
}
/**
* @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 ) );
}
public function provideTimezoneOffsets(): array {
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' ],
];
}
}