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:
Serreau Jovann
2026-04-04 00:05:00 +02:00
parent 817fad4150
commit 51585e33f8
3 changed files with 223 additions and 0 deletions

View 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
View 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;
}
}

View 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());
}
}