From 51585e33f8eeeab26ac0b30f7a931c6585f22259 Mon Sep 17 00:00:00 2001 From: Serreau Jovann Date: Sat, 4 Apr 2026 00:05:00 +0200 Subject: [PATCH] =?UTF-8?q?feat:=20entit=C3=A9=20DomainEmail=20li=C3=A9e?= =?UTF-8?q?=20=C3=A0=20Domain=20avec=20migration?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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) --- migrations/Version20260403220445.php | 34 ++++++++ src/Entity/DomainEmail.php | 118 +++++++++++++++++++++++++++ tests/Entity/DomainEmailTest.php | 71 ++++++++++++++++ 3 files changed, 223 insertions(+) create mode 100644 migrations/Version20260403220445.php create mode 100644 src/Entity/DomainEmail.php create mode 100644 tests/Entity/DomainEmailTest.php diff --git a/migrations/Version20260403220445.php b/migrations/Version20260403220445.php new file mode 100644 index 0000000..5e9b170 --- /dev/null +++ b/migrations/Version20260403220445.php @@ -0,0 +1,34 @@ +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'); + } +} diff --git a/src/Entity/DomainEmail.php b/src/Entity/DomainEmail.php new file mode 100644 index 0000000..2dc7d4a --- /dev/null +++ b/src/Entity/DomainEmail.php @@ -0,0 +1,118 @@ +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; + } +} diff --git a/tests/Entity/DomainEmailTest.php b/tests/Entity/DomainEmailTest.php new file mode 100644 index 0000000..220997e --- /dev/null +++ b/tests/Entity/DomainEmailTest.php @@ -0,0 +1,71 @@ +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()); + } +}