[Validator] Extra timezone tests

This commit is contained in:
Roland Franssen 2019-04-30 08:54:56 +02:00
parent 8fdcd6e6ef
commit 4f2bba7cb5
4 changed files with 52 additions and 27 deletions

View File

@ -44,8 +44,12 @@ class Timezone extends Constraint
{ {
parent::__construct($options); parent::__construct($options);
if ($this->countryCode && \DateTimeZone::PER_COUNTRY !== $this->zone) { if (null === $this->countryCode) {
throw new ConstraintDefinitionException('The option "countryCode" can only be used when "zone" option is configured with `\DateTimeZone::PER_COUNTRY`.'); if (0 >= $this->zone || \DateTimeZone::ALL_WITH_BC < $this->zone) {
throw new ConstraintDefinitionException('The option "zone" must be a valid range of "\DateTimeZone" constants.');
}
} elseif (\DateTimeZone::PER_COUNTRY !== (\DateTimeZone::PER_COUNTRY & $this->zone)) {
throw new ConstraintDefinitionException('The option "countryCode" can only be used when the "zone" option is configured with "\DateTimeZone::PER_COUNTRY".');
} }
} }
} }

View File

@ -45,12 +45,12 @@ class TimezoneValidator extends ConstraintValidator
// @see: https://bugs.php.net/bug.php?id=75928 // @see: https://bugs.php.net/bug.php?id=75928
if ($constraint->countryCode) { if ($constraint->countryCode) {
$timezoneIds = \DateTimeZone::listIdentifiers($constraint->zone, $constraint->countryCode); $timezoneIds = @\DateTimeZone::listIdentifiers($constraint->zone, $constraint->countryCode) ?: [];
} else { } else {
$timezoneIds = \DateTimeZone::listIdentifiers($constraint->zone); $timezoneIds = \DateTimeZone::listIdentifiers($constraint->zone);
} }
if ($timezoneIds && \in_array($value, $timezoneIds, true)) { if (\in_array($value, $timezoneIds, true)) {
return; return;
} }

View File

@ -21,30 +21,23 @@ class TimezoneTest extends TestCase
{ {
public function testValidTimezoneConstraints() public function testValidTimezoneConstraints()
{ {
$constraint = new Timezone(); new Timezone();
new Timezone(['zone' => \DateTimeZone::ALL]);
$constraint = new Timezone([ new Timezone(['zone' => \DateTimeZone::ALL_WITH_BC]);
'message' => 'myMessage', new Timezone([
'zone' => \DateTimeZone::PER_COUNTRY, 'zone' => \DateTimeZone::PER_COUNTRY,
'countryCode' => 'AR', 'countryCode' => 'AR',
]); ]);
$constraint = new Timezone([ $this->addToAssertionCount(1);
'message' => 'myMessage',
'zone' => \DateTimeZone::ALL,
]);
// Make an assertion in order to avoid this test to be marked as risky
$this->assertInstanceOf(Timezone::class, $constraint);
} }
/** /**
* @expectedException \Symfony\Component\Validator\Exception\ConstraintDefinitionException * @expectedException \Symfony\Component\Validator\Exception\ConstraintDefinitionException
*/ */
public function testExceptionForGroupedTimezonesByCountryWithWrongTimezone() public function testExceptionForGroupedTimezonesByCountryWithWrongZone()
{ {
$constraint = new Timezone([ new Timezone([
'message' => 'myMessage',
'zone' => \DateTimeZone::ALL, 'zone' => \DateTimeZone::ALL,
'countryCode' => 'AR', 'countryCode' => 'AR',
]); ]);
@ -53,11 +46,24 @@ class TimezoneTest extends TestCase
/** /**
* @expectedException \Symfony\Component\Validator\Exception\ConstraintDefinitionException * @expectedException \Symfony\Component\Validator\Exception\ConstraintDefinitionException
*/ */
public function testExceptionForGroupedTimezonesByCountryWithoutTimezone() public function testExceptionForGroupedTimezonesByCountryWithoutZone()
{ {
$constraint = new Timezone([ new Timezone(['countryCode' => 'AR']);
'message' => 'myMessage', }
'countryCode' => 'AR',
]); /**
* @dataProvider provideInvalidZones
* @expectedException \Symfony\Component\Validator\Exception\ConstraintDefinitionException
*/
public function testExceptionForInvalidGroupedTimezones(int $zone)
{
new Timezone(['zone' => $zone]);
}
public function provideInvalidZones(): iterable
{
yield [-1];
yield [0];
yield [\DateTimeZone::ALL_WITH_BC + 1];
} }
} }

View File

@ -189,19 +189,17 @@ class TimezoneValidatorTest extends ConstraintValidatorTestCase
yield ['Europe/Monaco', 'MC']; yield ['Europe/Monaco', 'MC'];
yield ['Indian/Christmas', 'CX']; yield ['Indian/Christmas', 'CX'];
yield ['Pacific/Kiritimati', 'KI']; yield ['Pacific/Kiritimati', 'KI'];
yield ['Pacific/Kiritimati', 'KI'];
yield ['Pacific/Kiritimati', 'KI'];
} }
/** /**
* @dataProvider getInvalidGroupedTimezonesByCountry * @dataProvider getInvalidGroupedTimezonesByCountry
*/ */
public function testInvalidGroupedTimezonesByCountry(string $timezone, string $invalidCountryCode) public function testInvalidGroupedTimezonesByCountry(string $timezone, string $countryCode)
{ {
$constraint = new Timezone([ $constraint = new Timezone([
'message' => 'myMessage', 'message' => 'myMessage',
'zone' => \DateTimeZone::PER_COUNTRY, 'zone' => \DateTimeZone::PER_COUNTRY,
'countryCode' => $invalidCountryCode, 'countryCode' => $countryCode,
]); ]);
$this->validator->validate($timezone, $constraint); $this->validator->validate($timezone, $constraint);
@ -217,6 +215,23 @@ class TimezoneValidatorTest extends ConstraintValidatorTestCase
yield ['America/Argentina/Cordoba', 'FR']; yield ['America/Argentina/Cordoba', 'FR'];
yield ['America/Barbados', 'PT']; yield ['America/Barbados', 'PT'];
yield ['Europe/Bern', 'FR']; yield ['Europe/Bern', 'FR'];
yield ['Europe/Amsterdam', 'AC']; // "AC" has no timezones, but is a valid country code
}
public function testGroupedTimezonesWithInvalidCountry()
{
$constraint = new Timezone([
'message' => 'myMessage',
'zone' => \DateTimeZone::PER_COUNTRY,
'countryCode' => 'foobar',
]);
$this->validator->validate('Europe/Amsterdam', $constraint);
$this->buildViolation('myMessage')
->setParameter('{{ value }}', '"Europe/Amsterdam"')
->setCode(Timezone::TIMEZONE_IDENTIFIER_IN_COUNTRY_ERROR)
->assertRaised();
} }
/** /**