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