- Add billing fields to User (isBilling, billingAmount, billingState, billingStripeSubscriptionId) and OrganizerInvitation (billingAmount) - Registration: organizer gets billingState="poor" (pending review) - Admin approval: sets isBilling=true, billingAmount from form, state="good" - Invitation: billingAmount from invitation, if 0 then isBilling=false - ROLE_ROOT accounts: billing free (amount=0, state="good") - Block Stripe Connect creation and all organizer features if state is "poor" or "suspendu" - Hide Stripe configuration section if billing not settled - Add billing checkout via Stripe subscription with success route - Webhooks: checkout.session.completed activates billing, invoice.payment_failed and customer.subscription.deleted suspend account and disable online events - Show billing alert on /mon-compte with amount and subscribe button - Display billing info in invitation email and landing page - Add email templates for billing activated/failed/cancelled Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
166 lines
4.9 KiB
PHP
166 lines
4.9 KiB
PHP
<?php
|
|
|
|
namespace App\Tests\Entity;
|
|
|
|
use App\Entity\OrganizerInvitation;
|
|
use PHPUnit\Framework\TestCase;
|
|
|
|
class OrganizerInvitationTest extends TestCase
|
|
{
|
|
public function testDefaults(): void
|
|
{
|
|
$inv = new OrganizerInvitation();
|
|
|
|
self::assertNull($inv->getId());
|
|
self::assertNull($inv->getCompanyName());
|
|
self::assertNull($inv->getFirstName());
|
|
self::assertNull($inv->getLastName());
|
|
self::assertNull($inv->getEmail());
|
|
self::assertNull($inv->getMessage());
|
|
self::assertNull($inv->getOffer());
|
|
self::assertNull($inv->getCommissionRate());
|
|
self::assertSame(OrganizerInvitation::STATUS_SENT, $inv->getStatus());
|
|
self::assertSame(64, \strlen($inv->getToken()));
|
|
self::assertNull($inv->getRespondedAt());
|
|
self::assertInstanceOf(\DateTimeImmutable::class, $inv->getCreatedAt());
|
|
}
|
|
|
|
public function testSetAndGetCompanyName(): void
|
|
{
|
|
$inv = new OrganizerInvitation();
|
|
$result = $inv->setCompanyName('Asso Test');
|
|
|
|
self::assertSame('Asso Test', $inv->getCompanyName());
|
|
self::assertSame($inv, $result);
|
|
}
|
|
|
|
public function testSetAndGetNames(): void
|
|
{
|
|
$inv = new OrganizerInvitation();
|
|
$inv->setFirstName('Jean');
|
|
$inv->setLastName('Dupont');
|
|
$inv->setEmail('jean@test.fr');
|
|
|
|
self::assertSame('Jean', $inv->getFirstName());
|
|
self::assertSame('Dupont', $inv->getLastName());
|
|
self::assertSame('jean@test.fr', $inv->getEmail());
|
|
}
|
|
|
|
public function testSetAndGetMessage(): void
|
|
{
|
|
$inv = new OrganizerInvitation();
|
|
$result = $inv->setMessage('Bienvenue !');
|
|
|
|
self::assertSame('Bienvenue !', $inv->getMessage());
|
|
self::assertSame($inv, $result);
|
|
|
|
$inv->setMessage(null);
|
|
self::assertNull($inv->getMessage());
|
|
}
|
|
|
|
public function testSetAndGetOffer(): void
|
|
{
|
|
$inv = new OrganizerInvitation();
|
|
$result = $inv->setOffer('basic');
|
|
|
|
self::assertSame('basic', $inv->getOffer());
|
|
self::assertSame($inv, $result);
|
|
}
|
|
|
|
public function testSetAndGetCommissionRate(): void
|
|
{
|
|
$inv = new OrganizerInvitation();
|
|
$result = $inv->setCommissionRate(5.5);
|
|
|
|
self::assertSame(5.5, $inv->getCommissionRate());
|
|
self::assertSame($inv, $result);
|
|
}
|
|
|
|
public function testSetAndGetBillingAmount(): void
|
|
{
|
|
$inv = new OrganizerInvitation();
|
|
|
|
self::assertNull($inv->getBillingAmount());
|
|
|
|
$result = $inv->setBillingAmount(1000);
|
|
|
|
self::assertSame(1000, $inv->getBillingAmount());
|
|
self::assertSame($inv, $result);
|
|
|
|
$inv->setBillingAmount(0);
|
|
self::assertSame(0, $inv->getBillingAmount());
|
|
}
|
|
|
|
public function testSetAndGetStatus(): void
|
|
{
|
|
$inv = new OrganizerInvitation();
|
|
$result = $inv->setStatus(OrganizerInvitation::STATUS_ACCEPTED);
|
|
|
|
self::assertSame(OrganizerInvitation::STATUS_ACCEPTED, $inv->getStatus());
|
|
self::assertSame($inv, $result);
|
|
}
|
|
|
|
public function testSetAndGetRespondedAt(): void
|
|
{
|
|
$inv = new OrganizerInvitation();
|
|
$date = new \DateTimeImmutable();
|
|
$result = $inv->setRespondedAt($date);
|
|
|
|
self::assertSame($date, $inv->getRespondedAt());
|
|
self::assertSame($inv, $result);
|
|
}
|
|
|
|
public function testUniqueTokens(): void
|
|
{
|
|
$inv1 = new OrganizerInvitation();
|
|
$inv2 = new OrganizerInvitation();
|
|
|
|
self::assertNotSame($inv1->getToken(), $inv2->getToken());
|
|
}
|
|
|
|
public function testIsExpiredFreshInvitation(): void
|
|
{
|
|
$inv = new OrganizerInvitation();
|
|
self::assertFalse($inv->isExpired());
|
|
}
|
|
|
|
public function testIsExpiredOldInvitation(): void
|
|
{
|
|
$inv = new OrganizerInvitation();
|
|
$ref = new \ReflectionProperty($inv, 'createdAt');
|
|
$ref->setValue($inv, new \DateTimeImmutable('-8 days'));
|
|
|
|
self::assertTrue($inv->isExpired());
|
|
}
|
|
|
|
public function testIsExpiredAcceptedNeverExpires(): void
|
|
{
|
|
$inv = new OrganizerInvitation();
|
|
$ref = new \ReflectionProperty($inv, 'createdAt');
|
|
$ref->setValue($inv, new \DateTimeImmutable('-30 days'));
|
|
$inv->setStatus(OrganizerInvitation::STATUS_ACCEPTED);
|
|
|
|
self::assertFalse($inv->isExpired());
|
|
}
|
|
|
|
public function testIsExpiredRefusedNeverExpires(): void
|
|
{
|
|
$inv = new OrganizerInvitation();
|
|
$ref = new \ReflectionProperty($inv, 'createdAt');
|
|
$ref->setValue($inv, new \DateTimeImmutable('-30 days'));
|
|
$inv->setStatus(OrganizerInvitation::STATUS_REFUSED);
|
|
|
|
self::assertFalse($inv->isExpired());
|
|
}
|
|
|
|
public function testIsExpiredCustomDays(): void
|
|
{
|
|
$inv = new OrganizerInvitation();
|
|
$ref = new \ReflectionProperty($inv, 'createdAt');
|
|
$ref->setValue($inv, new \DateTimeImmutable('-4 days'));
|
|
|
|
self::assertFalse($inv->isExpired(7));
|
|
self::assertTrue($inv->isExpired(3));
|
|
}
|
|
}
|