<?php

declare(strict_types=1);

/*
 * This file is part of the Ferienpass package.
 *
 * (c) Richard Henkenjohann <richard@ferienpass.online>
 *
 * For more information visit the project website <https://ferienpass.online>
 * or the documentation under <https://docs.ferienpass.online>.
 */

namespace Ferienpass\CoreBundle\Tests\Entity;

use Ferienpass\CoreBundle\Entity\AccessCode;
use Ferienpass\CoreBundle\Entity\AccessCodeStrategy;
use Ferienpass\CoreBundle\Entity\Participant\BaseParticipant;
use PHPUnit\Framework\TestCase;

final class AccessCodeTest extends TestCase
{
    public function testGetIdNullByDefault(): void
    {
        self::assertNull($this->makeCode()->getId());
    }

    public function testGetCreatedAtIsSetOnConstruct(): void
    {
        self::assertInstanceOf(\DateTimeInterface::class, $this->makeCode()->getCreatedAt());
    }

    public function testGetStrategy(): void
    {
        $strategy = $this->createStub(AccessCodeStrategy::class);
        $code = new AccessCode($strategy, 'XYZ');

        self::assertSame($strategy, $code->getStrategy());
    }

    public function testGetCode(): void
    {
        $code = $this->makeCode('HELLO');

        self::assertSame('HELLO', $code->getCode());
    }

    public function testSetCode(): void
    {
        $code = $this->makeCode();
        $code->setCode('NEWCODE');

        self::assertSame('NEWCODE', $code->getCode());
    }

    public function testParticipantsInitiallyEmpty(): void
    {
        self::assertCount(0, $this->makeCode()->getParticipants());
    }

    public function testAddParticipant(): void
    {
        $code = $this->makeCode();
        $participant = new BaseParticipant();

        $code->addParticipant($participant);

        self::assertCount(1, $code->getParticipants());
    }

    public function testRemoveParticipant(): void
    {
        $code = $this->makeCode();
        $participant = new BaseParticipant();

        $code->addParticipant($participant);
        self::assertCount(1, $code->getParticipants());

        $code->removeParticipant($participant);

        self::assertCount(0, $code->getParticipants());
    }

    private function makeCode(string $code = 'ABCDEF'): AccessCode
    {
        $strategy = $this->createStub(AccessCodeStrategy::class);

        return new AccessCode($strategy, $code);
    }
}
