<?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\ConsentManager;

use Ferienpass\CoreBundle\ConsentManager\ConsentManager;
use Ferienpass\CoreBundle\ConsentManager\ConsentRequirementChecker;
use Ferienpass\CoreBundle\ConsentManager\ConsentState;
use Ferienpass\CoreBundle\Entity\ConsentForm;
use Ferienpass\CoreBundle\Entity\Offer\OfferInterface;
use Ferienpass\CoreBundle\Entity\User;
use PHPUnit\Framework\TestCase;

final class ConsentRequirementCheckerTest extends TestCase
{
    public function testHasUnsignedConsentsReturnsTrueIfCompulsoryNotSigned(): void
    {
        $offer = $this->createMock(OfferInterface::class);
        $user = $this->createMock(User::class);
        $participants = [];

        $state = $this->createMock(ConsentState::class);
        $form = $this->createMock(ConsentForm::class);
        $form->method('isUserLevel')->willReturn(true);
        $state->method('getConsentForm')->willReturn($form);
        $state->method('isAcknowledged')->willReturn(true);
        $state->method('isCompulsory')->willReturn(true);
        $state->method('isSigned')->willReturn(false);
        $state->method('isOutstanding')->willReturn(true);

        $manager = $this->createMock(ConsentManager::class);
        $manager->method('forOfferAndParticipants')->willReturn([$state]);

        $checker = new ConsentRequirementChecker($manager);

        $this->assertTrue($checker->hasUnsignedConsents($offer, $participants, $user));
    }

    public function testHasUnsignedConsentsReturnsFalseIfAllCompulsorySigned(): void
    {
        $offer = $this->createMock(OfferInterface::class);
        $user = $this->createMock(User::class);
        $participants = [];

        $state = $this->createMock(ConsentState::class);
        $form = $this->createMock(ConsentForm::class);
        $form->method('isUserLevel')->willReturn(true);
        $state->method('getConsentForm')->willReturn($form);
        $state->method('isAcknowledged')->willReturn(true);
        $state->method('isCompulsory')->willReturn(true);
        $state->method('isSigned')->willReturn(true);
        $state->method('isOutstanding')->willReturn(false);

        $manager = $this->createMock(ConsentManager::class);
        $manager->method('forOfferAndParticipants')->willReturn([$state]);

        $checker = new ConsentRequirementChecker($manager);

        $this->assertFalse($checker->hasUnsignedConsents($offer, $participants, $user));
    }

    public function testHasUnsignedConsentsReturnsTrueIfNotAcknowledged(): void
    {
        $offer = $this->createMock(OfferInterface::class);
        $user = $this->createMock(User::class);
        $participants = [];

        $state = $this->createMock(ConsentState::class);
        $form = $this->createMock(ConsentForm::class);
        $form->method('isUserLevel')->willReturn(true);
        $state->method('getConsentForm')->willReturn($form);
        $state->method('isAcknowledged')->willReturn(false);
        $state->method('isOutstanding')->willReturn(true);

        $manager = $this->createMock(ConsentManager::class);
        $manager->method('forOfferAndParticipants')->willReturn([$state]);

        $checker = new ConsentRequirementChecker($manager);

        $this->assertTrue($checker->hasUnsignedConsents($offer, $participants, $user));
    }
}
