domain-watchdog/tests/Entity/DomainTest.php

255 lines
8.0 KiB
PHP
Raw Normal View History

2025-09-09 19:43:35 +02:00
<?php
declare(strict_types=1);
namespace App\Tests\Entity;
use App\Entity\Domain;
use App\Entity\DomainEvent;
use App\Entity\DomainStatus;
2025-10-22 18:22:36 +02:00
use App\Entity\Tld;
2025-10-16 14:16:58 +02:00
use App\Exception\MalformedDomainException;
2025-10-22 15:58:20 +02:00
use App\Service\RDAPService;
2025-10-22 18:22:36 +02:00
use App\Tests\Service\RDAPServiceTest;
use Doctrine\ORM\EntityManagerInterface;
use Doctrine\ORM\Exception\ORMException;
2025-09-09 19:43:35 +02:00
use PHPUnit\Framework\Attributes\DataProvider;
2025-10-22 18:22:36 +02:00
use PHPUnit\Framework\Attributes\DependsExternal;
use Symfony\Bundle\FrameworkBundle\Test\KernelTestCase;
2025-10-22 18:22:36 +02:00
use Symfony\Component\Uid\UuidV4;
2025-09-09 19:43:35 +02:00
class DomainTest extends KernelTestCase
2025-09-09 19:43:35 +02:00
{
public function testIsRedemptionPeriod(): void
{
$this->assertTrue(
(new Domain())
->setStatus(['redemption period'])
->isRedemptionPeriod()
);
$this->assertFalse(
(new Domain())
->setStatus(['active'])
->isRedemptionPeriod()
);
}
public function testIsPendingDelete(): void
{
$this->assertTrue(
(new Domain())
->setStatus(['pending delete'])
->isPendingDelete()
);
$this->assertFalse(
(new Domain())
->setStatus(['active'])
->isPendingDelete()
);
$this->assertFalse(
(new Domain())
->setStatus(['redemption period', 'pending delete'])
->isPendingDelete()
);
}
2025-10-22 18:22:36 +02:00
/**
* @throws MalformedDomainException
* @throws ORMException
*/
2025-10-22 22:11:28 +02:00
#[DataProvider('domainProvider')]
#[DependsExternal(RDAPServiceTest::class, 'testUpdateRdapServers')]
public function testGetExpiresInDays(
?int $expected,
array $status,
?DomainStatus $domainStatus,
?DomainEvent $domainEvent,
bool $deleted,
string $message,
): void {
2025-10-22 18:22:36 +02:00
/** @var EntityManagerInterface $entityManager */
$entityManager = self::getContainer()->get(EntityManagerInterface::class);
2025-10-22 22:11:28 +02:00
/** @var RDAPService $RDAPService */
$RDAPService = self::getContainer()->get(RDAPService::class);
2025-10-22 18:35:17 +02:00
/** @var Tld $arpaTld */
2025-10-22 18:43:18 +02:00
$arpaTld = $entityManager->getReference(Tld::class, 'arpa');
2025-10-22 18:22:36 +02:00
2025-10-22 22:11:28 +02:00
$domain = (new Domain())
2025-10-22 18:43:18 +02:00
->setLdhName((new UuidV4())->toString().'.arpa')
2025-10-22 18:22:36 +02:00
->setTld($arpaTld)
2025-10-22 22:11:28 +02:00
->setDeleted($deleted)
->setStatus($status);
2025-10-22 18:22:36 +02:00
2025-10-22 22:11:28 +02:00
$entityManager->persist($domain);
2025-10-22 18:22:36 +02:00
2025-10-22 22:11:28 +02:00
if (null !== $domainEvent) {
$entityManager->persist($domainEvent);
$domain->addEvent($domainEvent);
}
2025-10-22 18:22:36 +02:00
2025-10-22 22:11:28 +02:00
if (null !== $domainStatus) {
$entityManager->persist($domainStatus);
$domain->addDomainStatus($domainStatus);
}
2025-10-22 18:22:36 +02:00
$entityManager->flush();
2025-10-22 22:11:28 +02:00
$this->assertEquals($expected, $RDAPService->getExpiresInDays($domain), $message);
}
public static function domainProvider(): array
{
$now = new \DateTimeImmutable();
2025-10-22 18:22:36 +02:00
return [
2025-10-22 22:11:28 +02:00
[
null,
[],
null,
null,
true,
'No guess if the domain is flagged as deleted',
],
[
90,
[],
null,
(new DomainEvent())->setDate($now->add(new \DateInterval('P10D')))->setAction('expiration')->setDeleted(false),
false,
'Guess based on domain events date',
],
[
5,
['pending delete'],
(new DomainStatus())->setDate($now)->setCreatedAt($now)->setAddStatus(['pending delete'])->setDeleteStatus(['active']),
null,
false,
'Guess based on domain EPP status',
],
[
35,
['redemption period'],
(new DomainStatus())->setDate($now)->setCreatedAt($now)->setAddStatus(['redemption period'])->setDeleteStatus(['active']),
null,
false,
'Domain name entered in the redemption period',
],
[
0,
['pending delete'],
null,
(new DomainEvent())->setDate($now)->setAction('deletion')->setDeleted(false),
false,
'Domain name entered in the pending delete period',
],
[
null,
['pending delete'],
null,
null,
false,
'Not enough data to guess',
],
2025-10-22 18:22:36 +02:00
];
2025-09-09 19:43:35 +02:00
}
2025-10-16 14:16:58 +02:00
public function testIdnDomainName(): void
2025-09-09 19:43:35 +02:00
{
2025-09-10 00:11:05 +02:00
/*
2025-09-09 19:43:35 +02:00
* @see https://en.wikipedia.org/wiki/IDN_Test_TLDs
*/
$this->assertEquals('xn--zckzah',
(new Domain())->setLdhName('テスト')->getLdhName(),
'IDN TLD'
);
$this->assertEquals('xn--r8jz45g.xn--zckzah',
(new Domain())->setLdhName('例え.テスト')->getLdhName(),
'IDN Domain Name'
);
$this->assertEquals('test.xn--r8jz45g.xn--zckzah',
(new Domain())->setLdhName('test.例え.テスト')->getLdhName(),
'IDN FQDN'
);
}
2025-10-16 14:16:58 +02:00
public function testInvalidDomainName()
{
$this->expectException(MalformedDomainException::class);
(new Domain())->setLdhName('*');
}
2025-09-09 19:43:35 +02:00
public static function isToBeUpdatedProvider(): array
{
2025-09-10 00:11:05 +02:00
$now = new \DateTimeImmutable();
2025-09-09 19:43:35 +02:00
return [
// 1. updatedAt >= 7 days -> true
[$now->modify('-8 days'), false, false, false, 10, false, [], true],
// 2. deleted = true && fromUser = true -> true
[$now->modify('-1 day'), true, true, false, 10, false, [], true],
// 3. deleted = true && fromUser = false -> false
[$now->modify('-1 day'), true, false, false, 10, false, [], false],
// 4. intensifyLastDay = true && expiresIn = 0 -> true
[$now->modify('-1 hour'), false, false, true, 0, false, [], true],
// 5. intensifyLastDay = true && expiresIn = 1 -> true
[$now->modify('-1 hour'), false, false, true, 1, false, [], true],
// 6. watchClosely = true && minutesDiff >= 12 -> true
[$now->modify('-15 minutes'), false, false, false, 5, true, [], true],
// 7. watchClosely = true && fromUser = true (minutesDiff < 12) -> true
[$now->modify('-1 minute'), false, true, false, 5, true, [], true],
// 8. status = "client hold" && updatedAt >= 1 jour -> true
[$now->modify('-2 days'), false, false, false, 10, false, ['client hold'], true],
// 9. no cases -> false
[$now->modify('-1 hour'), false, false, false, 10, false, [], false],
];
}
/**
2025-09-10 00:11:05 +02:00
* @throws \Exception
2025-09-09 19:43:35 +02:00
*/
#[DataProvider('isToBeUpdatedProvider')]
public function testIsToBeUpdated(
2025-09-10 00:11:05 +02:00
\DateTimeImmutable $updatedAt,
bool $deleted,
bool $fromUser,
bool $intensifyLastDay,
int $expiresIn,
bool $watchClosely,
array $status,
bool $expected,
): void {
2025-10-22 15:58:20 +02:00
$rdapServiceMock = $this->getMockBuilder(RDAPService::class)
->disableOriginalConstructor()
2025-10-22 15:58:20 +02:00
->onlyMethods(['getExpiresInDays'])
->getMock();
$domainMock = $this->getMockBuilder(Domain::class)
->onlyMethods(['getUpdatedAt', 'getDeleted', 'isToBeWatchClosely', 'getStatus'])
2025-09-09 19:43:35 +02:00
->getMock();
2025-10-22 15:58:20 +02:00
$domainMock->method('getUpdatedAt')->willReturn($updatedAt);
$domainMock->method('getDeleted')->willReturn($deleted);
$rdapServiceMock->method('getExpiresInDays')->willReturn($expiresIn);
$domainMock->method('isToBeWatchClosely')->willReturn($watchClosely);
$domainMock->method('getStatus')->willReturn($status);
2025-09-09 19:43:35 +02:00
2025-10-22 15:58:20 +02:00
$result = $rdapServiceMock->isToBeUpdated($domainMock, $fromUser, $intensifyLastDay);
2025-09-09 19:43:35 +02:00
$this->assertEquals($expected, $result);
}
}