packages/requirements/tests/Unit/Source/ResourceLocationTest.php

1<?php
2
3declare(strict_types=1);
4
5namespace Tests\Unit\Source;
6
7use PHPUnit\Framework\Attributes\CoversClass;
8use PHPUnit\Framework\Attributes\DataProvider;
9use PHPUnit\Framework\Attributes\Small;
10use PHPUnit\Framework\TestCase;
11use Requirements\Source\ResourceLocation;
12use RuntimeException;
13
14#[CoversClass(ResourceLocation::class)]
15#[Small]
16final class ResourceLocationTest extends TestCase
17{
18    #[DataProvider('providerResolve')]
19    public function testResolve(string $uri, string $expected): void
20    {
21        self::assertSame($expected, (new ResourceLocation())->resolve($uri, '/project/config'));
22    }
23
24    /**
25     * @return array<string, array{string, string}>
26     */
27    public static function providerResolve(): array
28    {
29        return [
30            'relative path' => ['docs/manual.html', '/project/config/docs/manual.html'],
31            'parent path' => ['../manual.html', '/project/config/../manual.html'],
32            'absolute path' => ['/srv/manual.html', '/srv/manual.html'],
33            'https' => ['https://example.org/manual.html', 'https://example.org/manual.html'],
34            'http' => ['http://example.org/manual.html', 'http://example.org/manual.html'],
35        ];
36    }
37
38    #[DataProvider('providerResolveOtherScheme')]
39    public function testResolveRejectsOtherSchemes(string $uri): void
40    {
41        $this->expectException(RuntimeException::class);
42        $this->expectExceptionMessage('Built-in sources accept HTTP(S) URLs or local paths only.');
43        (new ResourceLocation())->resolve($uri, '/project/config');
44    }
45
46    /**
47     * @return array<string, array{string}>
48     */
49    public static function providerResolveOtherScheme(): array
50    {
51        return [
52            'file' => ['file:///etc/passwd'],
53            'ftp' => ['ftp://example.org/manual.html'],
54            'scheme inside an absolute path' => ['/srv/ftp://manual.html'],
55            'http later in the uri' => ['php://filter/http://example.org'],
56            'uppercase https' => ['HTTPS://example.org/manual.html'],
57        ];
58    }
59}
60