<?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\DocStoreBundle\Tests\Dav\Request;

use Chill\DocStoreBundle\Dav\Request\PropfindRequestAnalyzer;
use PHPUnit\Framework\TestCase;

/**
 * @internal
 *
 * @coversNothing
 */
class PropfindRequestAnalyzerTest extends TestCase
{
    /**
     * @dataProvider provideRequestedProperties
     */
    public function testGetRequestedProperties(string $xml, array $expected): void
    {
        $analyzer = new PropfindRequestAnalyzer();

        $request = new \DOMDocument();
        $request->loadXML($xml);
        $actual = $analyzer->getRequestedProperties($request);

        foreach ($expected as $key => $value) {
            if ('unknowns' === $key) {
                continue;
            }

            self::assertArrayHasKey($key, $actual, "Check that key {$key} does exists in list of expected values");
            self::assertEquals($value, $actual[$key], "Does the value match expected for key {$key}");
        }

        if (array_key_exists('unknowns', $expected)) {
            self::assertEquals(count($expected['unknowns']), count($actual['unknowns']));
            self::assertEqualsCanonicalizing($expected['unknowns'], $actual['unknowns']);
        }
    }

    public static function provideRequestedProperties(): iterable
    {
        yield [
            <<<'XML'
            <?xml version="1.0" encoding="UTF-8"?>
            <propfind xmlns="DAV:">
                <prop>
                    <BaseURI xmlns="http://ucb.openoffice.org/dav/props/"/>
                </prop>
            </propfind>
            XML,
            [
                'resourceType' => false,
                'contentType' => false,
                'lastModified' => false,
                'creationDate' => false,
                'contentLength' => false,
                'etag' => false,
                'supportedLock' => false,
                'unknowns' => [
                    ['xmlns' => 'http://ucb.openoffice.org/dav/props/', 'prop' => 'BaseURI'],
                ],
            ],
        ];

        yield [
            <<<'XML'
            <?xml version="1.0" encoding="UTF-8"?>
              <propfind xmlns="DAV:">
                <propname/>
              </propfind>
            XML,
            [
                'resourceType' => true,
                'contentType' => true,
                'lastModified' => true,
                'creationDate' => true,
                'contentLength' => true,
                'etag' => true,
                'supportedLock' => true,
                'unknowns' => [],
            ],
        ];

        yield [
            <<<'XML'
            <?xml version="1.0" encoding="UTF-8"?>
              <propfind xmlns="DAV:">
                <prop>
                  <getlastmodified xmlns="DAV:"/>
                </prop>
              </propfind>
            XML,
            [
                'resourceType' => false,
                'contentType' => false,
                'lastModified' => true,
                'creationDate' => false,
                'contentLength' => false,
                'etag' => false,
                'supportedLock' => false,
                'unknowns' => [],
            ],
        ];

        yield [
            <<<'XML'
            <?xml version="1.0" encoding="UTF-8"?>
            <propfind xmlns="DAV:"><prop><resourcetype xmlns="DAV:"/><IsReadOnly xmlns="http://ucb.openoffice.org/dav/props/"/><getcontenttype xmlns="DAV:"/><supportedlock xmlns="DAV:"/></prop></propfind>
            XML,
            [
                'resourceType' => true,
                'contentType' => true,
                'lastModified' => false,
                'creationDate' => false,
                'contentLength' => false,
                'etag' => false,
                'supportedLock' => false,
                'unknowns' => [
                    ['xmlns' => 'http://ucb.openoffice.org/dav/props/', 'prop' => 'IsReadOnly'],
                ],
            ],
        ];
    }
}
