<?php

namespace Velis\Test\Dto\Utility;

use PHPUnit\Framework\TestCase;
use ReflectionClass;
use ReflectionException;
use Velis\Dto\RelationTransformer\Relation;
use Velis\Dto\Utility\PropertyUtility;
use Velis\Dto\Utility\Unfiltered;

class PropertyUtilityTest extends TestCase
{
    /**
     * @throws ReflectionException
     */
    public function testGetPublicProperties(): void
    {
        $object = new class {
            public string $name;
            private string $secret;
        };

        $properties = PropertyUtility::getPublicProperties($object);

        $this->assertCount(1, $properties);

        $property = $properties[0];
        $this->assertEquals('name', $property->getName());
    }

    /**
     * @param class-string $attribute
     * @throws ReflectionException
     *
     * @dataProvider provideHasAttribute
     */
    public function testHasAttribute(
        object $object,
        string $propertyName,
        string $attribute,
        bool $expectedResult,
    ): void {
        $reflectionClass = new ReflectionClass($object);
        $property = $reflectionClass->getProperty($propertyName);

        $actualResult = PropertyUtility::hasAttribute($property, $attribute);

        $this->assertEquals($expectedResult, $actualResult);
    }

    /**
     * @return array<array{object, string, class-string, bool}>
     */
    public function provideHasAttribute(): array
    {
        $object = new class {
            #[Unfiltered]
            public string $unfilteredProperty;

            public string $filteredProperty;
        };

        return [
            [
                $object,
                'unfilteredProperty',
                Unfiltered::class,
                true,
            ],
            [
                $object,
                'filteredProperty',
                Unfiltered::class,
                false,
            ],
            [
                $object,
                'unfilteredProperty',
                Relation::class,
                false,
            ],
        ];
    }
}
