<?PHP
/**
 * This script contains tests for the validation of single field contents.
 *
 * @author Joshua Ramon Enslin <joshua@museum-digital.de>
 */
declare(strict_types = 1);

use PHPUnit\Framework\TestCase;
use PHPUnit\Framework\Attributes\CoversClass;
use PHPUnit\Framework\Attributes\Small;

/**
 * This script contains tests for the validation of single field contents.
 */
#[small]
#[CoversClass(\NodaValidationHelper::class)]
final class NodaValidationHelperTest extends TestCase {
    /**
     * Test that a specific error is thrown if no description for actors is provided.
     *
     * @return void
     */
    public function testActorDescriptionValidationFailsOnEmptyInput():void {

        $this->expectException(MDInvalidEmptyInputException::class);
        NodaValidationHelper::validateActorDescription("");

    }

    /**
     * Test successfully refusing too short actor descriptions.
     *
     * @return void
     */
    public function testActorDescriptionValidationFailsOnTooShortInput():void {

        $this->expectException(MDgenericInvalidInputsException::class);
        NodaValidationHelper::validateActorDescription("abc");

    }

    /**
     * Test successfully refusing actor descriptions that have too few distinct characters.
     *
     * @return void
     */
    public function testActorDescriptionValidationFailsOnTooFewDistinctCharacters():void {

        $this->expectException(MDgenericInvalidInputsException::class);
        NodaValidationHelper::validateActorDescription("aaaaaaaaaaaa");

    }

    /**
     * Test successfully refusing actor descriptions that simply duplicate the actor name.
     *
     * @return void
     */
    public function testActorDescriptionValidationFailsOnDuplicatedActorNames():void {

        $this->expectException(MDgenericInvalidInputsException::class);
        NodaValidationHelper::validateActorDescription("Richard Lepsius", ["Lepsius, Richard"]);
        $this->expectException(MDgenericInvalidInputsException::class);
        NodaValidationHelper::validateActorDescription("Richard Lepsius", ["Lepsius", "Richard"]);
        $this->expectException(MDgenericInvalidInputsException::class);
        NodaValidationHelper::validateActorDescription("Lepsius, Richard", ["Lepsius", "Richard"]);
        $this->expectException(MDgenericInvalidInputsException::class);
        NodaValidationHelper::validateActorDescription("Richard Lepsius, ", ["Lepsius", "Richard"]);
        $this->expectException(MDgenericInvalidInputsException::class);
        NodaValidationHelper::validateActorDescription("Helmut Testtest", ["Helmut Testtest", "Helmut Testtest", "Testtest, Helmut", "Helmut", "Testtest"]);

    }

    /**
     * Test that a valid description is accepted.
     *
     * @return void
     */
    public function testActorDescriptionValidationAcceptsValidDescription():void {

        self::expectNotToPerformAssertions();
        NodaValidationHelper::validateActorDescription("Richard Lepsius war ein Forscher", ["Lepsius", "Richard"]);

    }

    /**
     * Test that a specific error is thrown if no description for tags is provided.
     *
     * @return void
     */
    public function testTagDescriptionValidationFailsOnEmptyInput():void {

        $this->expectException(MDInvalidEmptyInputException::class);
        NodaValidationHelper::validateTagDescription("");

    }

    /**
     * Test successfully refusing too short tag descriptions.
     *
     * @return void
     */
    public function testTagDescriptionValidationFailsOnTooShortInput():void {

        $this->expectException(MDgenericInvalidInputsException::class);
        NodaValidationHelper::validateTagDescription("abc");

    }

    /**
     * Test successfully refusing tag descriptions that have too few distinct characters.
     *
     * @return void
     */
    public function testTagDescriptionValidationFailsOnTooFewDistinctCharacters():void {

        $this->expectException(MDgenericInvalidInputsException::class);
        NodaValidationHelper::validateTagDescription("aaaaaaaaaaaa");

    }

    /**
     * Test successfully refusing tag descriptions that simply duplicate the tag name.
     *
     * @return void
     */
    public function testTagDescriptionValidationFailsOnDuplicatedTagNames():void {

        $this->expectException(MDgenericInvalidInputsException::class);
        NodaValidationHelper::validateTagDescription("Richard Lepsius", "Richard Lepsius");
        $this->expectException(MDgenericInvalidInputsException::class);
        NodaValidationHelper::validateTagDescription("Richard Lepsius", "Lepsius Richard");
        $this->expectException(MDgenericInvalidInputsException::class);
        NodaValidationHelper::validateTagDescription("Lepsius, Richard", "Lepsius, Richard");

    }

    /**
     * Test that a valid description is accepted.
     *
     * @return void
     */
    public function testTagDescriptionValidationAcceptsValidDescription():void {

        self::expectNotToPerformAssertions();
        NodaValidationHelper::validateTagDescription("Richard Lepsius war ein Forscher", "Richard Lepsius");

    }
}
