feat: entité DomainEmail liée à Domain avec migration
Entity DomainEmail : - domain (ManyToOne, CASCADE) : domaine parent - name : partie locale de l'email (lowercase auto, ex: contact) - state : active/suspended/disabled (défaut active) - quotaMb : quota en Mo (défaut 5120 = 5 Go) - createdAt / updatedAt : timestamps (updatedAt auto sur setState) - getFullEmail() : retourne name@domain.fqdn - isActive() : vérifie si state === active DomainEmailTest (3 tests, 19 assertions) : - testConstructor : valeurs par défaut, name lowercase/trim, fullEmail - testSetters : name, quotaMb, updatedAt - testState : active→suspended→disabled, updatedAt mis à jour Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
34
migrations/Version20260403220445.php
Normal file
34
migrations/Version20260403220445.php
Normal file
@@ -0,0 +1,34 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace DoctrineMigrations;
|
||||
|
||||
use Doctrine\DBAL\Schema\Schema;
|
||||
use Doctrine\Migrations\AbstractMigration;
|
||||
|
||||
/**
|
||||
* Auto-generated Migration: Please modify to your needs!
|
||||
*/
|
||||
final class Version20260403220445 extends AbstractMigration
|
||||
{
|
||||
public function getDescription(): string
|
||||
{
|
||||
return '';
|
||||
}
|
||||
|
||||
public function up(Schema $schema): void
|
||||
{
|
||||
// this up() migration is auto-generated, please modify it to your needs
|
||||
$this->addSql('CREATE TABLE domain_email (id INT GENERATED BY DEFAULT AS IDENTITY NOT NULL, name VARCHAR(255) NOT NULL, state VARCHAR(20) NOT NULL, quota_mb INT NOT NULL, created_at TIMESTAMP(0) WITHOUT TIME ZONE NOT NULL, updated_at TIMESTAMP(0) WITHOUT TIME ZONE DEFAULT NULL, domain_id INT NOT NULL, PRIMARY KEY (id))');
|
||||
$this->addSql('CREATE INDEX IDX_34E954A2115F0EE5 ON domain_email (domain_id)');
|
||||
$this->addSql('ALTER TABLE domain_email ADD CONSTRAINT FK_34E954A2115F0EE5 FOREIGN KEY (domain_id) REFERENCES domain (id) ON DELETE CASCADE NOT DEFERRABLE');
|
||||
}
|
||||
|
||||
public function down(Schema $schema): void
|
||||
{
|
||||
// this down() migration is auto-generated, please modify it to your needs
|
||||
$this->addSql('ALTER TABLE domain_email DROP CONSTRAINT FK_34E954A2115F0EE5');
|
||||
$this->addSql('DROP TABLE domain_email');
|
||||
}
|
||||
}
|
||||
118
src/Entity/DomainEmail.php
Normal file
118
src/Entity/DomainEmail.php
Normal file
@@ -0,0 +1,118 @@
|
||||
<?php
|
||||
|
||||
namespace App\Entity;
|
||||
|
||||
use Doctrine\ORM\Mapping as ORM;
|
||||
|
||||
#[ORM\Entity]
|
||||
class DomainEmail
|
||||
{
|
||||
public const STATE_ACTIVE = 'active';
|
||||
public const STATE_SUSPENDED = 'suspended';
|
||||
public const STATE_DISABLED = 'disabled';
|
||||
|
||||
#[ORM\Id]
|
||||
#[ORM\GeneratedValue]
|
||||
#[ORM\Column]
|
||||
private ?int $id = null;
|
||||
|
||||
#[ORM\ManyToOne(targetEntity: Domain::class)]
|
||||
#[ORM\JoinColumn(nullable: false, onDelete: 'CASCADE')]
|
||||
private Domain $domain;
|
||||
|
||||
#[ORM\Column(length: 255)]
|
||||
private string $name;
|
||||
|
||||
#[ORM\Column(length: 20)]
|
||||
private string $state = self::STATE_ACTIVE;
|
||||
|
||||
#[ORM\Column]
|
||||
private int $quotaMb = 5120;
|
||||
|
||||
#[ORM\Column]
|
||||
private \DateTimeImmutable $createdAt;
|
||||
|
||||
#[ORM\Column(nullable: true)]
|
||||
private ?\DateTimeImmutable $updatedAt = null;
|
||||
|
||||
public function __construct(Domain $domain, string $name)
|
||||
{
|
||||
$this->domain = $domain;
|
||||
$this->name = strtolower(trim($name));
|
||||
$this->createdAt = new \DateTimeImmutable();
|
||||
}
|
||||
|
||||
public function getId(): ?int
|
||||
{
|
||||
return $this->id;
|
||||
}
|
||||
|
||||
public function getDomain(): Domain
|
||||
{
|
||||
return $this->domain;
|
||||
}
|
||||
|
||||
public function getName(): string
|
||||
{
|
||||
return $this->name;
|
||||
}
|
||||
|
||||
public function setName(string $name): static
|
||||
{
|
||||
$this->name = strtolower(trim($name));
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getFullEmail(): string
|
||||
{
|
||||
return $this->name.'@'.$this->domain->getFqdn();
|
||||
}
|
||||
|
||||
public function getState(): string
|
||||
{
|
||||
return $this->state;
|
||||
}
|
||||
|
||||
public function setState(string $state): static
|
||||
{
|
||||
$this->state = $state;
|
||||
$this->updatedAt = new \DateTimeImmutable();
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function isActive(): bool
|
||||
{
|
||||
return self::STATE_ACTIVE === $this->state;
|
||||
}
|
||||
|
||||
public function getQuotaMb(): int
|
||||
{
|
||||
return $this->quotaMb;
|
||||
}
|
||||
|
||||
public function setQuotaMb(int $quotaMb): static
|
||||
{
|
||||
$this->quotaMb = $quotaMb;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getCreatedAt(): \DateTimeImmutable
|
||||
{
|
||||
return $this->createdAt;
|
||||
}
|
||||
|
||||
public function getUpdatedAt(): ?\DateTimeImmutable
|
||||
{
|
||||
return $this->updatedAt;
|
||||
}
|
||||
|
||||
public function setUpdatedAt(?\DateTimeImmutable $updatedAt): static
|
||||
{
|
||||
$this->updatedAt = $updatedAt;
|
||||
|
||||
return $this;
|
||||
}
|
||||
}
|
||||
71
tests/Entity/DomainEmailTest.php
Normal file
71
tests/Entity/DomainEmailTest.php
Normal file
@@ -0,0 +1,71 @@
|
||||
<?php
|
||||
|
||||
namespace App\Tests\Entity;
|
||||
|
||||
use App\Entity\Customer;
|
||||
use App\Entity\Domain;
|
||||
use App\Entity\DomainEmail;
|
||||
use App\Entity\User;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
class DomainEmailTest extends TestCase
|
||||
{
|
||||
private function createDomain(): Domain
|
||||
{
|
||||
$user = new User();
|
||||
$user->setEmail('c@t.com');
|
||||
$user->setFirstName('C');
|
||||
$user->setLastName('T');
|
||||
$user->setPassword('h');
|
||||
|
||||
return new Domain(new Customer($user), 'siteconseil.fr');
|
||||
}
|
||||
|
||||
public function testConstructor(): void
|
||||
{
|
||||
$domain = $this->createDomain();
|
||||
$email = new DomainEmail($domain, ' Contact ');
|
||||
|
||||
$this->assertNull($email->getId());
|
||||
$this->assertSame($domain, $email->getDomain());
|
||||
$this->assertSame('contact', $email->getName());
|
||||
$this->assertSame('contact@siteconseil.fr', $email->getFullEmail());
|
||||
$this->assertSame(DomainEmail::STATE_ACTIVE, $email->getState());
|
||||
$this->assertTrue($email->isActive());
|
||||
$this->assertSame(5120, $email->getQuotaMb());
|
||||
$this->assertInstanceOf(\DateTimeImmutable::class, $email->getCreatedAt());
|
||||
$this->assertNull($email->getUpdatedAt());
|
||||
}
|
||||
|
||||
public function testSetters(): void
|
||||
{
|
||||
$email = new DomainEmail($this->createDomain(), 'info');
|
||||
|
||||
$email->setName(' Support ');
|
||||
$this->assertSame('support', $email->getName());
|
||||
$this->assertSame('support@siteconseil.fr', $email->getFullEmail());
|
||||
|
||||
$email->setQuotaMb(10240);
|
||||
$this->assertSame(10240, $email->getQuotaMb());
|
||||
|
||||
$now = new \DateTimeImmutable();
|
||||
$email->setUpdatedAt($now);
|
||||
$this->assertSame($now, $email->getUpdatedAt());
|
||||
}
|
||||
|
||||
public function testState(): void
|
||||
{
|
||||
$email = new DomainEmail($this->createDomain(), 'test');
|
||||
|
||||
$this->assertTrue($email->isActive());
|
||||
|
||||
$email->setState(DomainEmail::STATE_SUSPENDED);
|
||||
$this->assertSame(DomainEmail::STATE_SUSPENDED, $email->getState());
|
||||
$this->assertFalse($email->isActive());
|
||||
$this->assertInstanceOf(\DateTimeImmutable::class, $email->getUpdatedAt());
|
||||
|
||||
$email->setState(DomainEmail::STATE_DISABLED);
|
||||
$this->assertSame(DomainEmail::STATE_DISABLED, $email->getState());
|
||||
$this->assertFalse($email->isActive());
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user