<?php

declare(strict_types=1);

/*
 * Chill is a software for social workers
 *
 * For the full copyright and license information, please view
 * the LICENSE file that was distributed with this source code.
 */

namespace Chill\PersonBundle\Tests\Validator\AccompanyingPeriod;

use Chill\PersonBundle\Entity\AccompanyingPeriod;
use Chill\PersonBundle\Entity\Person;
use Chill\PersonBundle\Templating\Entity\PersonRender;
use Chill\PersonBundle\Validator\Constraints\AccompanyingPeriod\LocationValidity;
use Chill\PersonBundle\Validator\Constraints\AccompanyingPeriod\LocationValidityValidator;
use Symfony\Component\Validator\Test\ConstraintValidatorTestCase;

/**
 * @internal
 *
 * @coversNothing
 */
final class LocationValidityValidatorTest extends ConstraintValidatorTestCase
{
    public function testPeriodDoesNotContainsPersonOnAnyPerson()
    {
        $constraint = $this->getConstraint();

        $period = new AccompanyingPeriod();
        $person1 = new Person();
        $period->setPersonLocation($person1);

        $this->validator->validate($period, $constraint);

        $this->buildViolation('messagePersonLocatedMustBeAssociated')
            ->setParameters([
                '{{ person_name }}' => 'name',
            ])
            ->assertRaised();
    }

    public function testPeriodDoesNotContainsPersonOnOtherPerson()
    {
        $constraint = $this->getConstraint();

        $period = new AccompanyingPeriod();
        $person1 = new Person();
        $person2 = new Person();
        $period->addPerson($person1);

        $period->setPersonLocation($person2);

        $this->validator->validate($period, $constraint);

        $this->buildViolation('messagePersonLocatedMustBeAssociated')
            ->setParameters([
                '{{ person_name }}' => 'name',
            ])
            ->assertRaised();
    }

    public function testPeriodDoesNotContainsPersonOnRemovedPerson()
    {
        $constraint = $this->getConstraint();

        $period = new AccompanyingPeriod();
        $person1 = new Person();
        $period->addPerson($person1);

        $period->setPersonLocation($person1);

        $period->removePerson($person1);

        $this->validator->validate($period, $constraint);

        $this->buildViolation('messagePersonLocatedMustBeAssociated')
            ->setParameters([
                '{{ person_name }}' => 'name',
            ])
            ->assertRaised();
    }

    public function testRemoveLocationOnPeriodValidated()
    {
        $constraint = $this->getConstraint();

        $period = new AccompanyingPeriod();
        $period->setStep('not draft');

        $this->validator->validate($period, $constraint);

        $this->buildViolation('messagePeriodMustRemainsLocated')
            ->assertRaised();
    }

    public function testValidAddress()
    {
        $constraint = $this->getConstraint();

        $period = new AccompanyingPeriod();
        $person = new Person();
        $period->addPerson($person);

        $period->setPersonLocation($person);

        $this->validator->validate($period, $constraint);

        $this->assertNoViolation();
    }

    protected function createValidator()
    {
        $render = $this->createMock(PersonRender::class);
        $render->method('renderString')
            ->willReturn('name');

        return new LocationValidityValidator($render);
    }

    protected function getConstraint()
    {
        return new LocationValidity([
            'messagePersonLocatedMustBeAssociated' => 'messagePersonLocatedMustBeAssociated',
            'messagePeriodMustRemainsLocated' => 'messagePeriodMustRemainsLocated',
        ]);
    }
}
