1<?php 2 3/** 4 * webtrees: online genealogy 5 * Copyright (C) 2022 webtrees development team 6 * This program is free software: you can redistribute it and/or modify 7 * it under the terms of the GNU General Public License as published by 8 * the Free Software Foundation, either version 3 of the License, or 9 * (at your option) any later version. 10 * This program is distributed in the hope that it will be useful, 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 * GNU General Public License for more details. 14 * You should have received a copy of the GNU General Public License 15 * along with this program. If not, see <https://www.gnu.org/licenses/>. 16 */ 17 18declare(strict_types=1); 19 20namespace Fisharebest\Webtrees; 21 22use Fisharebest\Webtrees\Http\Exceptions\HttpBadRequestException; 23use Psr\Http\Message\ServerRequestInterface; 24 25/** 26 * Test harness for the class Validator 27 */ 28class ValidatorTest extends TestCase 29{ 30 /** 31 * @covers \Fisharebest\Webtrees\Validator::array 32 */ 33 public function testRequiredArrayParameter(): void 34 { 35 $request = $this->createStub(ServerRequestInterface::class); 36 $parameters = ['param' => ['test'], 'invalid' => 'not_array']; 37 $validator = new Validator($parameters, $request); 38 39 self::assertSame(['test'], $validator->array('param')); 40 41 $this->expectException(HttpBadRequestException::class); 42 $validator->array('invalid'); 43 } 44 45 /** 46 * @covers \Fisharebest\Webtrees\Validator::integer 47 */ 48 public function testRequiredIntegerParameter(): void 49 { 50 $request = $this->createStub(ServerRequestInterface::class); 51 $parameters = [ 52 'int_type_positive' => 42, 53 'int_type_negative' => -42, 54 'string_type_positive' => '42', 55 'string_type_negative' => '-42', 56 'invalid' => 'not_int', 57 ]; 58 $validator = new Validator($parameters, $request); 59 60 self::assertSame(42, $validator->integer('int_type_positive')); 61 self::assertSame(-42, $validator->integer('int_type_negative')); 62 self::assertSame(42, $validator->integer('string_type_positive')); 63 self::assertSame(-42, $validator->integer('string_type_negative')); 64 65 $this->expectException(HttpBadRequestException::class); 66 $validator->integer('invalid'); 67 } 68 69 /** 70 * @covers \Fisharebest\Webtrees\Validator::string 71 */ 72 public function testRequiredStringParameter(): void 73 { 74 $request = $this->createStub(ServerRequestInterface::class); 75 $parameters = ['param' => 'test', 'invalid' => ['not_string']]; 76 $validator = new Validator($parameters, $request); 77 78 self::assertSame('test', $validator->string('param')); 79 80 $this->expectException(HttpBadRequestException::class); 81 $validator->string('invalid'); 82 } 83 84 /** 85 * @covers \Fisharebest\Webtrees\Validator::isBetween 86 */ 87 public function testIsBetweenParameter(): void 88 { 89 $request = $this->createStub(ServerRequestInterface::class); 90 $parameters = ['param' => '42', 'invalid' => '10', 'wrongtype' => 'not_integer']; 91 $validator = (new Validator($parameters, $request))->isBetween(40, 45); 92 93 self::assertSame(42, $validator->integer('param')); 94 self::assertSame(42, $validator->integer('invalid', 42)); 95 self::assertSame(42, $validator->integer('wrongtype', 42)); 96 } 97 98 /** 99 * @covers \Fisharebest\Webtrees\Validator::isXref 100 */ 101 public function testIsXrefParameter(): void 102 { 103 $request = $this->createStub(ServerRequestInterface::class); 104 $parameters = ['param' => 'X1', 'invalid' => '@X1@']; 105 $validator = (new Validator($parameters, $request))->isXref(); 106 107 self::assertSame('X1', $validator->string('param')); 108 109 $this->expectException(HttpBadRequestException::class); 110 $validator->string('invalid'); 111 } 112 113 /** 114 * @covers \Fisharebest\Webtrees\Validator::isLocalUrl 115 */ 116 public function testIsLocalUrlParameter(): void 117 { 118 $request = $this->createStub(ServerRequestInterface::class); 119 $request->method('getAttribute')->with('base_url')->willReturn('http://example.local/wt'); 120 121 $parameters = ['param' => 'http://example.local/wt/page', 'noscheme' => '//example.local/wt/page']; 122 $validator = (new Validator($parameters, $request))->isLocalUrl(); 123 124 self::assertSame('http://example.local/wt/page', $validator->string('param')); 125 self::assertSame('//example.local/wt/page', $validator->string('noscheme')); 126 } 127 128 /** 129 * @covers \Fisharebest\Webtrees\Validator::isLocalUrl 130 */ 131 public function testIsLocalUrlParameterWrongScheme(): void 132 { 133 $request = $this->createStub(ServerRequestInterface::class); 134 $request->method('getAttribute')->with('base_url')->willReturn('http://example.local/wt'); 135 136 $parameters = ['https' => 'https://example.local/wt/page']; 137 $validator = (new Validator($parameters, $request))->isLocalUrl(); 138 139 $this->expectException(HttpBadRequestException::class); 140 $validator->string('https'); 141 } 142 143 /** 144 * @covers \Fisharebest\Webtrees\Validator::isLocalUrl 145 */ 146 public function testIsLocalUrlParameterWrongDomain(): void 147 { 148 $request = $this->createStub(ServerRequestInterface::class); 149 $request->method('getAttribute')->with('base_url')->willReturn('http://example.local/wt'); 150 151 $parameters = ['invalid' => 'http://example.com/wt/page']; 152 $validator = (new Validator($parameters, $request))->isLocalUrl(); 153 154 $this->expectException(HttpBadRequestException::class); 155 $validator->string('invalid'); 156 } 157 158 /** 159 * @covers \Fisharebest\Webtrees\Validator::isLocalUrl 160 */ 161 public function testIsLocalUrlParameterWrongType(): void 162 { 163 $request = $this->createStub(ServerRequestInterface::class); 164 $parameters = ['wrongtype' => ['42']]; 165 $validator = (new Validator($parameters, $request))->isLocalUrl(); 166 167 $this->expectException(HttpBadRequestException::class); 168 $validator->string('wrongtype'); 169 } 170 171 /** 172 * @covers \Fisharebest\Webtrees\Validator::__construct 173 * @covers \Fisharebest\Webtrees\Validator::parsedBody 174 */ 175 public function testParsedBody(): void 176 { 177 $request = self::createRequest()->withParsedBody(['param' => 'test']); 178 self::assertSame('test', Validator::parsedBody($request)->string('param')); 179 180 $this->expectException(HttpBadRequestException::class); 181 $request = self::createRequest()->withQueryParams(['param' => 'test']); 182 Validator::parsedBody($request)->string('param'); 183 } 184 185 /** 186 * @covers \Fisharebest\Webtrees\Validator::__construct 187 * @covers \Fisharebest\Webtrees\Validator::queryParams 188 */ 189 public function testQueryParams(): void 190 { 191 $request = self::createRequest()->withQueryParams(['param' => 'test']); 192 self::assertSame('test', Validator::queryParams($request)->string('param')); 193 194 $this->expectException(HttpBadRequestException::class); 195 $request = self::createRequest()->withParsedBody(['param' => 'test']); 196 Validator::queryParams($request)->string('param'); 197 } 198} 199