xref: /webtrees/tests/app/ValidatorTest.php (revision 62ff2f188c699b1144fb2ca2d6da1358d5e1a745)
1f6fdd746SJonathan Jaubart<?php
2f6fdd746SJonathan Jaubart
3f6fdd746SJonathan Jaubart/**
4f6fdd746SJonathan Jaubart * webtrees: online genealogy
5d11be702SGreg Roach * Copyright (C) 2023 webtrees development team
6f6fdd746SJonathan Jaubart * This program is free software: you can redistribute it and/or modify
7f6fdd746SJonathan Jaubart * it under the terms of the GNU General Public License as published by
8f6fdd746SJonathan Jaubart * the Free Software Foundation, either version 3 of the License, or
9f6fdd746SJonathan Jaubart * (at your option) any later version.
10f6fdd746SJonathan Jaubart * This program is distributed in the hope that it will be useful,
11f6fdd746SJonathan Jaubart * but WITHOUT ANY WARRANTY; without even the implied warranty of
12f6fdd746SJonathan Jaubart * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13f6fdd746SJonathan Jaubart * GNU General Public License for more details.
14f6fdd746SJonathan Jaubart * You should have received a copy of the GNU General Public License
15f6fdd746SJonathan Jaubart * along with this program. If not, see <https://www.gnu.org/licenses/>.
16f6fdd746SJonathan Jaubart */
17f6fdd746SJonathan Jaubart
18f6fdd746SJonathan Jaubartdeclare(strict_types=1);
19f6fdd746SJonathan Jaubart
20f6fdd746SJonathan Jaubartnamespace Fisharebest\Webtrees;
21f6fdd746SJonathan Jaubart
22a5f003cfSGreg Roachuse Aura\Router\Route;
23a5f003cfSGreg Roachuse Fisharebest\Webtrees\Contracts\UserInterface;
24f6fdd746SJonathan Jaubartuse Fisharebest\Webtrees\Http\Exceptions\HttpBadRequestException;
25202c018bSGreg Roachuse PHPUnit\Framework\Attributes\CoversClass;
26f507cef9SGreg Roachuse Psr\Http\Message\ServerRequestInterface;
27f6fdd746SJonathan Jaubart
28202c018bSGreg Roach
29202c018bSGreg Roach#[CoversClass(Validator::class)]
30f6fdd746SJonathan Jaubartclass ValidatorTest extends TestCase
31f6fdd746SJonathan Jaubart{
32a5f003cfSGreg Roach    public function testAttributes(): void
33a5f003cfSGreg Roach    {
34*62ff2f18SGreg Roach        $request = $this->createMock(ServerRequestInterface::class);
35a5f003cfSGreg Roach        $request
36a5f003cfSGreg Roach            ->method('getAttributes')
37a5f003cfSGreg Roach            ->willReturn(['param' => 'test']);
38a5f003cfSGreg Roach
39a5f003cfSGreg Roach        self::assertSame('test', Validator::attributes($request)->string('param'));
40a5f003cfSGreg Roach    }
41a5f003cfSGreg Roach
42a5f003cfSGreg Roach    public function testParsedBody(): void
43a5f003cfSGreg Roach    {
44*62ff2f18SGreg Roach        $request = $this->createMock(ServerRequestInterface::class);
45a5f003cfSGreg Roach        $request
46a5f003cfSGreg Roach            ->method('getParsedBody')
47a5f003cfSGreg Roach            ->willReturn(['param' => 'test']);
48a5f003cfSGreg Roach
49a5f003cfSGreg Roach        self::assertSame('test', Validator::parsedBody($request)->string('param'));
50a5f003cfSGreg Roach    }
51a5f003cfSGreg Roach
52a5f003cfSGreg Roach    public function testQueryParams(): void
53a5f003cfSGreg Roach    {
54*62ff2f18SGreg Roach        $request = $this->createMock(ServerRequestInterface::class);
55a5f003cfSGreg Roach        $request
56a5f003cfSGreg Roach            ->method('getQueryParams')
57a5f003cfSGreg Roach            ->willReturn(['param' => 'test']);
58a5f003cfSGreg Roach
59a5f003cfSGreg Roach        self::assertSame('test', Validator::queryParams($request)->string('param'));
60a5f003cfSGreg Roach    }
61a5f003cfSGreg Roach
62a5f003cfSGreg Roach    public function testServerParams(): void
63a5f003cfSGreg Roach    {
64*62ff2f18SGreg Roach        $request = $this->createMock(ServerRequestInterface::class);
65a5f003cfSGreg Roach        $request
66a5f003cfSGreg Roach            ->method('getServerParams')
67a5f003cfSGreg Roach            ->willReturn(['param' => 'test']);
68a5f003cfSGreg Roach
69a5f003cfSGreg Roach        self::assertSame('test', Validator::serverParams($request)->string('param'));
70a5f003cfSGreg Roach    }
71a5f003cfSGreg Roach
72a5f003cfSGreg Roach    public function testNonUTF8QueryParameterName(): void
73a5f003cfSGreg Roach    {
74*62ff2f18SGreg Roach        $request = $this->createMock(ServerRequestInterface::class);
75a5f003cfSGreg Roach        $request
76a5f003cfSGreg Roach            ->method('getQueryParams')
77a5f003cfSGreg Roach            ->willReturn(["\xFF" => 'test']);
78a5f003cfSGreg Roach
79a5f003cfSGreg Roach        $this->expectException(HttpBadRequestException::class);
80a5f003cfSGreg Roach
81a5f003cfSGreg Roach        Validator::queryParams($request);
82a5f003cfSGreg Roach    }
83a5f003cfSGreg Roach
84a5f003cfSGreg Roach    public function testNonUTF8QueryParameterValue(): void
85a5f003cfSGreg Roach    {
86*62ff2f18SGreg Roach        $request = $this->createMock(ServerRequestInterface::class);
87a5f003cfSGreg Roach        $request
88a5f003cfSGreg Roach            ->method('getQueryParams')
89a5f003cfSGreg Roach            ->willReturn(['test' => "\xFF"]);
90a5f003cfSGreg Roach
91a5f003cfSGreg Roach        $this->expectException(HttpBadRequestException::class);
92a5f003cfSGreg Roach
93a5f003cfSGreg Roach        Validator::queryParams($request);
94a5f003cfSGreg Roach    }
95a5f003cfSGreg Roach
96f6fdd746SJonathan Jaubart    public function testRequiredArrayParameter(): void
97f6fdd746SJonathan Jaubart    {
98*62ff2f18SGreg Roach        $request = $this->createMock(ServerRequestInterface::class);
99a5f003cfSGreg Roach        $request
100a5f003cfSGreg Roach            ->method('getQueryParams')
101a5f003cfSGreg Roach            ->willReturn(['param' => ['test'], 'invalid' => 'not_array']);
102f6fdd746SJonathan Jaubart
103a5f003cfSGreg Roach
104a5f003cfSGreg Roach        self::assertSame(['test'], Validator::queryParams($request)->array('param'));
105f6fdd746SJonathan Jaubart
106f6fdd746SJonathan Jaubart        $this->expectException(HttpBadRequestException::class);
107a5f003cfSGreg Roach
108a5f003cfSGreg Roach        Validator::queryParams($request)->array('invalid');
109a5f003cfSGreg Roach    }
110a5f003cfSGreg Roach
111a5f003cfSGreg Roach    public function testRequiredBooleanParameter(): void
112a5f003cfSGreg Roach    {
113*62ff2f18SGreg Roach        $request = $this->createMock(ServerRequestInterface::class);
114a5f003cfSGreg Roach        $request
115a5f003cfSGreg Roach            ->method('getQueryParams')
116a5f003cfSGreg Roach            ->willReturn([
117a5f003cfSGreg Roach                'a'    => '1',
118a5f003cfSGreg Roach                'b'    => 'on',
119a5f003cfSGreg Roach                'c'    => true,
120a5f003cfSGreg Roach                'd' => '0',
121a5f003cfSGreg Roach                'e' => '',
122a5f003cfSGreg Roach                'f' => false,
123a5f003cfSGreg Roach            ]);
124a5f003cfSGreg Roach
125a5f003cfSGreg Roach        self::assertSame(true, Validator::queryParams($request)->boolean('a'));
126a5f003cfSGreg Roach        self::assertSame(true, Validator::queryParams($request)->boolean('b'));
127a5f003cfSGreg Roach        self::assertSame(true, Validator::queryParams($request)->boolean('c'));
128a5f003cfSGreg Roach        self::assertSame(false, Validator::queryParams($request)->boolean('d'));
129a5f003cfSGreg Roach        self::assertSame(false, Validator::queryParams($request)->boolean('e'));
130a5f003cfSGreg Roach        self::assertSame(false, Validator::queryParams($request)->boolean('f'));
131a5f003cfSGreg Roach        self::assertSame(false, Validator::queryParams($request)->boolean('g', false));
132a5f003cfSGreg Roach
133a5f003cfSGreg Roach        $this->expectException(HttpBadRequestException::class);
134a5f003cfSGreg Roach
135a5f003cfSGreg Roach        Validator::queryParams($request)->boolean('h');
136f6fdd746SJonathan Jaubart    }
137f6fdd746SJonathan Jaubart
138f6fdd746SJonathan Jaubart    public function testRequiredIntegerParameter(): void
139f6fdd746SJonathan Jaubart    {
140*62ff2f18SGreg Roach        $request = $this->createMock(ServerRequestInterface::class);
141a5f003cfSGreg Roach        $request
142a5f003cfSGreg Roach            ->method('getQueryParams')
143a5f003cfSGreg Roach            ->willReturn([
14465625b93SGreg Roach                'int_type_positive'    => 42,
14565625b93SGreg Roach                'int_type_negative'    => -42,
14665625b93SGreg Roach                'string_type_positive' => '42',
14765625b93SGreg Roach                'string_type_negative' => '-42',
14865625b93SGreg Roach                'invalid'              => 'not_int',
149a5f003cfSGreg Roach            ]);
150f6fdd746SJonathan Jaubart
151a5f003cfSGreg Roach        self::assertSame(42, Validator::queryParams($request)->integer('int_type_positive'));
152a5f003cfSGreg Roach        self::assertSame(-42, Validator::queryParams($request)->integer('int_type_negative'));
153a5f003cfSGreg Roach        self::assertSame(42, Validator::queryParams($request)->integer('string_type_positive'));
154a5f003cfSGreg Roach        self::assertSame(-42, Validator::queryParams($request)->integer('string_type_negative'));
155f6fdd746SJonathan Jaubart
156f6fdd746SJonathan Jaubart        $this->expectException(HttpBadRequestException::class);
157a5f003cfSGreg Roach
158a5f003cfSGreg Roach        Validator::queryParams($request)->integer('invalid');
159a5f003cfSGreg Roach    }
160a5f003cfSGreg Roach
161a5f003cfSGreg Roach    public function testRequiredRouteParameter(): void
162a5f003cfSGreg Roach    {
163*62ff2f18SGreg Roach        $route = $this->createMock(Route::class);
164a5f003cfSGreg Roach
165*62ff2f18SGreg Roach        $request = $this->createMock(ServerRequestInterface::class);
166a5f003cfSGreg Roach        $request
167a5f003cfSGreg Roach            ->method('getQueryParams')
168a5f003cfSGreg Roach            ->willReturn([
169a5f003cfSGreg Roach                'valid-route' => $route,
170a5f003cfSGreg Roach                'not-route'   => '',
171a5f003cfSGreg Roach            ]);
172a5f003cfSGreg Roach
173a5f003cfSGreg Roach        self::assertSame($route, Validator::queryParams($request)->route('valid-route'));
174a5f003cfSGreg Roach
175a5f003cfSGreg Roach        $this->expectException(HttpBadRequestException::class);
176a5f003cfSGreg Roach
177a5f003cfSGreg Roach        Validator::queryParams($request)->route('not-route');
178f6fdd746SJonathan Jaubart    }
179f6fdd746SJonathan Jaubart
180f6fdd746SJonathan Jaubart    public function testRequiredStringParameter(): void
181f6fdd746SJonathan Jaubart    {
182*62ff2f18SGreg Roach        $request = $this->createMock(ServerRequestInterface::class);
183a5f003cfSGreg Roach        $request
184a5f003cfSGreg Roach            ->method('getQueryParams')
185a5f003cfSGreg Roach            ->willReturn(['param' => 'test', 'invalid' => ['not_string']]);
186f6fdd746SJonathan Jaubart
187a5f003cfSGreg Roach        self::assertSame('test', Validator::queryParams($request)->string('param'));
188f6fdd746SJonathan Jaubart
189f6fdd746SJonathan Jaubart        $this->expectException(HttpBadRequestException::class);
190a5f003cfSGreg Roach
191a5f003cfSGreg Roach        Validator::queryParams($request)->string('invalid');
192a5f003cfSGreg Roach    }
193a5f003cfSGreg Roach
194a5f003cfSGreg Roach    public function testRequiredTreeParameter(): void
195a5f003cfSGreg Roach    {
196*62ff2f18SGreg Roach        $tree = $this->createMock(Tree::class);
197a5f003cfSGreg Roach
198*62ff2f18SGreg Roach        $request = $this->createMock(ServerRequestInterface::class);
199a5f003cfSGreg Roach        $request
200a5f003cfSGreg Roach            ->method('getQueryParams')
201a5f003cfSGreg Roach            ->willReturn([
202a5f003cfSGreg Roach                'valid-tree' => $tree,
203a5f003cfSGreg Roach                'not-tree'   => '',
204a5f003cfSGreg Roach            ]);
205a5f003cfSGreg Roach
206a5f003cfSGreg Roach        self::assertSame($tree, Validator::queryParams($request)->tree('valid-tree'));
207a5f003cfSGreg Roach
208a5f003cfSGreg Roach        $this->expectException(HttpBadRequestException::class);
209a5f003cfSGreg Roach
210a5f003cfSGreg Roach        Validator::queryParams($request)->tree('no-tree');
211a5f003cfSGreg Roach    }
212a5f003cfSGreg Roach
213a5f003cfSGreg Roach    public function testOptionalTreeParameter(): void
214a5f003cfSGreg Roach    {
215*62ff2f18SGreg Roach        $tree = $this->createMock(Tree::class);
216a5f003cfSGreg Roach
217*62ff2f18SGreg Roach        $request = $this->createMock(ServerRequestInterface::class);
218a5f003cfSGreg Roach        $request
219a5f003cfSGreg Roach            ->method('getQueryParams')
220a5f003cfSGreg Roach            ->willReturn([
221a5f003cfSGreg Roach                'valid-tree' => $tree,
222a5f003cfSGreg Roach                'not-tree'   => '',
223a5f003cfSGreg Roach            ]);
224a5f003cfSGreg Roach
225a5f003cfSGreg Roach        self::assertSame($tree, Validator::queryParams($request)->treeOptional('valid-tree'));
226a5f003cfSGreg Roach        self::assertSame(null, Validator::queryParams($request)->treeOptional('missing-tree'));
227a5f003cfSGreg Roach
228a5f003cfSGreg Roach        $this->expectException(HttpBadRequestException::class);
229a5f003cfSGreg Roach
230a5f003cfSGreg Roach        Validator::queryParams($request)->treeOptional('not-tree');
231a5f003cfSGreg Roach    }
232a5f003cfSGreg Roach
233a5f003cfSGreg Roach    public function testRequiredUserParameter(): void
234a5f003cfSGreg Roach    {
235*62ff2f18SGreg Roach        $user = $this->createMock(UserInterface::class);
236a5f003cfSGreg Roach
237*62ff2f18SGreg Roach        $request = $this->createMock(ServerRequestInterface::class);
238a5f003cfSGreg Roach        $request
239a5f003cfSGreg Roach            ->method('getQueryParams')
240a5f003cfSGreg Roach            ->willReturn([
241a5f003cfSGreg Roach                'valid-user' => $user,
242a5f003cfSGreg Roach                'not-user'   => '',
243a5f003cfSGreg Roach            ]);
244a5f003cfSGreg Roach
245a5f003cfSGreg Roach        self::assertSame($user, Validator::queryParams($request)->user('valid-user'));
246a5f003cfSGreg Roach
247a5f003cfSGreg Roach        $this->expectException(HttpBadRequestException::class);
248a5f003cfSGreg Roach
249a5f003cfSGreg Roach        Validator::queryParams($request)->user('not-user');
250f6fdd746SJonathan Jaubart    }
251f6fdd746SJonathan Jaubart
252f6fdd746SJonathan Jaubart    public function testIsBetweenParameter(): void
253f6fdd746SJonathan Jaubart    {
254*62ff2f18SGreg Roach        $request = $this->createMock(ServerRequestInterface::class);
255a5f003cfSGreg Roach        $request
256a5f003cfSGreg Roach            ->method('getQueryParams')
257a5f003cfSGreg Roach            ->willReturn(['param' => '42', 'invalid' => '10', 'wrongtype' => 'not_integer']);
258f6fdd746SJonathan Jaubart
259a5f003cfSGreg Roach        self::assertSame(42, Validator::queryParams($request)->isBetween(40, 45)->integer('param'));
260a5f003cfSGreg Roach        self::assertSame(42, Validator::queryParams($request)->isBetween(40, 45)->integer('invalid', 42));
261a5f003cfSGreg Roach        self::assertSame(42, Validator::queryParams($request)->isBetween(40, 45)->integer('wrongtype', 42));
262a5f003cfSGreg Roach    }
263a5f003cfSGreg Roach
264a5f003cfSGreg Roach    public function testIsInArray(): void
265a5f003cfSGreg Roach    {
266*62ff2f18SGreg Roach        $request = $this->createMock(ServerRequestInterface::class);
267a5f003cfSGreg Roach        $request
268a5f003cfSGreg Roach            ->method('getQueryParams')
269a5f003cfSGreg Roach            ->willReturn(['param' => 'foo']);
270a5f003cfSGreg Roach
271a5f003cfSGreg Roach        self::assertSame('foo', Validator::queryParams($request)->isInArray(['foo', 'bar'])->string('param'));
272a5f003cfSGreg Roach
273a5f003cfSGreg Roach        $this->expectException(HttpBadRequestException::class);
274a5f003cfSGreg Roach
275a5f003cfSGreg Roach        Validator::queryParams($request)->isInArray(['baz'])->string('param');
276a5f003cfSGreg Roach    }
277a5f003cfSGreg Roach
278a5f003cfSGreg Roach    public function testIsInArrayKeys(): void
279a5f003cfSGreg Roach    {
280*62ff2f18SGreg Roach        $request = $this->createMock(ServerRequestInterface::class);
281a5f003cfSGreg Roach        $request
282a5f003cfSGreg Roach            ->method('getQueryParams')
283a5f003cfSGreg Roach            ->willReturn(['param' => 'foo']);
284a5f003cfSGreg Roach
285a5f003cfSGreg Roach        self::assertSame('foo', Validator::queryParams($request)->isInArrayKeys(['foo' => 1, 'bar' => 2])->string('param'));
286a5f003cfSGreg Roach
287a5f003cfSGreg Roach        $this->expectException(HttpBadRequestException::class);
288a5f003cfSGreg Roach
289a5f003cfSGreg Roach        Validator::queryParams($request)->isInArrayKeys(['baz' => 3])->string('param');
290a5f003cfSGreg Roach    }
291a5f003cfSGreg Roach
292a5f003cfSGreg Roach    public function testIsNotEmpty(): void
293a5f003cfSGreg Roach    {
294*62ff2f18SGreg Roach        $request = $this->createMock(ServerRequestInterface::class);
295a5f003cfSGreg Roach        $request
296a5f003cfSGreg Roach            ->method('getQueryParams')
297a5f003cfSGreg Roach            ->willReturn(['empty' => '', 'not-empty' => 'foo']);
298a5f003cfSGreg Roach
299a5f003cfSGreg Roach        self::assertSame('foo', Validator::queryParams($request)->isNotEmpty()->string('not-empty'));
300a5f003cfSGreg Roach
301a5f003cfSGreg Roach        $this->expectException(HttpBadRequestException::class);
302a5f003cfSGreg Roach
303a5f003cfSGreg Roach        Validator::queryParams($request)->isNotEmpty()->string('empty');
304a5f003cfSGreg Roach    }
305a5f003cfSGreg Roach
306a5f003cfSGreg Roach    public function testIsTagParameter(): void
307a5f003cfSGreg Roach    {
308*62ff2f18SGreg Roach        $request = $this->createMock(ServerRequestInterface::class);
309a5f003cfSGreg Roach        $request
310a5f003cfSGreg Roach            ->method('getQueryParams')
311a5f003cfSGreg Roach            ->willReturn(['valid' => 'BIRT', 'invalid' => '@X1@']);
312a5f003cfSGreg Roach
313a5f003cfSGreg Roach        self::assertSame('BIRT', Validator::queryParams($request)->isTag()->string('valid'));
314a5f003cfSGreg Roach
315a5f003cfSGreg Roach        $this->expectException(HttpBadRequestException::class);
316a5f003cfSGreg Roach
317a5f003cfSGreg Roach        Validator::queryParams($request)->isTag()->string('invalid');
318f6fdd746SJonathan Jaubart    }
319f6fdd746SJonathan Jaubart
320f6fdd746SJonathan Jaubart    public function testIsXrefParameter(): void
321f6fdd746SJonathan Jaubart    {
322*62ff2f18SGreg Roach        $request = $this->createMock(ServerRequestInterface::class);
323a5f003cfSGreg Roach        $request
324a5f003cfSGreg Roach            ->method('getQueryParams')
325a5f003cfSGreg Roach            ->willReturn(['valid' => 'X1', 'invalid' => '@X1@', 'valid-array' => ['X1'], 'invalid-array' => ['@X1@']]);
326f6fdd746SJonathan Jaubart
327a5f003cfSGreg Roach        self::assertSame('X1', Validator::queryParams($request)->isXref()->string('valid'));
328a5f003cfSGreg Roach        self::assertSame(['X1'], Validator::queryParams($request)->isXref()->array('valid-array'));
329a5f003cfSGreg Roach        self::assertSame([], Validator::queryParams($request)->isXref()->array('invalid-array'));
3301e60ebf4SGreg Roach
3311e60ebf4SGreg Roach        $this->expectException(HttpBadRequestException::class);
332a5f003cfSGreg Roach
333a5f003cfSGreg Roach        Validator::queryParams($request)->isXref()->string('invalid');
334f6fdd746SJonathan Jaubart    }
335f6fdd746SJonathan Jaubart
336f6fdd746SJonathan Jaubart    public function testIsLocalUrlParameter(): void
337f6fdd746SJonathan Jaubart    {
338*62ff2f18SGreg Roach        $request = $this->createMock(ServerRequestInterface::class);
339a5f003cfSGreg Roach        $request
340a5f003cfSGreg Roach            ->method('getAttribute')
341a5f003cfSGreg Roach            ->with('base_url')->willReturn('http://example.local/wt');
342a5f003cfSGreg Roach        $request
343a5f003cfSGreg Roach            ->method('getQueryParams')
344a5f003cfSGreg Roach            ->willReturn(['param' => 'http://example.local/wt/page', 'noscheme' => '//example.local/wt/page']);
345f507cef9SGreg Roach
3461e60ebf4SGreg Roach
347a5f003cfSGreg Roach        self::assertSame('http://example.local/wt/page', Validator::queryParams($request)->isLocalUrl()->string('param'));
348a5f003cfSGreg Roach        self::assertSame('//example.local/wt/page', Validator::queryParams($request)->isLocalUrl()->string('noscheme'));
3491e60ebf4SGreg Roach    }
3501e60ebf4SGreg Roach
3511e60ebf4SGreg Roach    public function testIsLocalUrlParameterWrongScheme(): void
3521e60ebf4SGreg Roach    {
353*62ff2f18SGreg Roach        $request = $this->createMock(ServerRequestInterface::class);
354a5f003cfSGreg Roach        $request
355a5f003cfSGreg Roach            ->method('getAttribute')
356a5f003cfSGreg Roach            ->with('base_url')
357a5f003cfSGreg Roach            ->willReturn('http://example.local/wt');
358a5f003cfSGreg Roach        $request
359a5f003cfSGreg Roach            ->method('getQueryParams')
360a5f003cfSGreg Roach            ->willReturn(['https' => 'https://example.local/wt/page']);
3611e60ebf4SGreg Roach
3621e60ebf4SGreg Roach        $this->expectException(HttpBadRequestException::class);
363a5f003cfSGreg Roach
364a5f003cfSGreg Roach        Validator::queryParams($request)->isLocalUrl()->string('https');
3651e60ebf4SGreg Roach    }
3661e60ebf4SGreg Roach
3671e60ebf4SGreg Roach    public function testIsLocalUrlParameterWrongDomain(): void
3681e60ebf4SGreg Roach    {
369*62ff2f18SGreg Roach        $request = $this->createMock(ServerRequestInterface::class);
370a5f003cfSGreg Roach        $request
371a5f003cfSGreg Roach            ->method('getAttribute')
372a5f003cfSGreg Roach            ->with('base_url')
373a5f003cfSGreg Roach            ->willReturn('http://example.local/wt');
374a5f003cfSGreg Roach        $request
375a5f003cfSGreg Roach            ->method('getQueryParams')
376a5f003cfSGreg Roach            ->willReturn(['invalid' => 'http://example.com/wt/page']);
3771e60ebf4SGreg Roach
3781e60ebf4SGreg Roach        $this->expectException(HttpBadRequestException::class);
379a5f003cfSGreg Roach
380a5f003cfSGreg Roach        Validator::queryParams($request)->isLocalUrl()->string('invalid');
3811e60ebf4SGreg Roach    }
3821e60ebf4SGreg Roach
3831e60ebf4SGreg Roach    public function testIsLocalUrlParameterWrongType(): void
3841e60ebf4SGreg Roach    {
385*62ff2f18SGreg Roach        $request = $this->createMock(ServerRequestInterface::class);
386a5f003cfSGreg Roach        $request
387a5f003cfSGreg Roach            ->method('getQueryParams')
388a5f003cfSGreg Roach            ->willReturn(['wrongtype' => ['42']]);
389f6fdd746SJonathan Jaubart
3901e60ebf4SGreg Roach        $this->expectException(HttpBadRequestException::class);
391f6fdd746SJonathan Jaubart
392a5f003cfSGreg Roach        Validator::queryParams($request)->isLocalUrl()->isLocalUrl()->string('wrongtype');
393f6fdd746SJonathan Jaubart    }
394f6fdd746SJonathan Jaubart}
395