-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
11 changed files
with
219 additions
and
42 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
<?hh // strict | ||
|
||
namespace Nazg\Foundation\Validation; | ||
|
||
use Exception; | ||
|
||
class ValidationException extends Exception { | ||
|
||
protected int $status = 400; | ||
|
||
protected Validator $validator; | ||
|
||
public function __construct(Validator $validator) { | ||
parent::__construct('The given data was invalid.'); | ||
$this->validator = $validator; | ||
} | ||
|
||
public function errors(): array<string> { | ||
return $this->validator->errors()->toArray(); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,55 @@ | ||
<?hh // strict | ||
|
||
namespace Nazg\Foundation\Validation; | ||
|
||
use Psr\Http\Message\ServerRequestInterface; | ||
use Facebook\TypeAssert; | ||
|
||
enum Attribute: string as string { | ||
Named = 'RequestValidation'; | ||
} | ||
|
||
<<__ConsistentConstruct>> | ||
abstract class Validator { | ||
|
||
protected ?ServerRequestInterface $request; | ||
|
||
protected Vector<string> $messages = Vector{}; | ||
|
||
protected Vector<string> $validateMethods = Vector{}; | ||
|
||
protected bool $shouldThrowException = false; | ||
|
||
// disabled type assert for request parameters | ||
protected bool $skipValidateStructure = true; | ||
|
||
public function validateRequest(ServerRequestInterface $request): void { | ||
$this->request = $request; | ||
} | ||
|
||
public function validate(): bool { | ||
if (!is_null($this->request)) { | ||
$this->assertStructure(); | ||
} | ||
if($this->errors()->count()) { | ||
if ($this->shouldThrowException) { | ||
throw new ValidationException($this); | ||
} | ||
return false; | ||
} | ||
return true; | ||
} | ||
|
||
<<__Memoize>> | ||
public function errors(): ImmVector<string> { | ||
return $this->assertValidateResult()->immutable(); | ||
} | ||
|
||
protected function assertStructure(): void { | ||
if(!$this->skipValidateStructure) { | ||
// here | ||
} | ||
} | ||
|
||
abstract protected function assertValidateResult(): Vector<string>; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
<?hh // strict | ||
|
||
use Nazg\Foundation\Validation\Validator; | ||
use Psr\Http\Message\ServerRequestInterface; | ||
|
||
final class MockValidateActionFaild extends Validator { | ||
|
||
protected bool $shouldThrowException = true; | ||
|
||
protected function assertValidateResult(): Vector<string> { | ||
return new Vector(['error1']); | ||
} | ||
} |
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,108 @@ | ||
<?hh | ||
|
||
use Facebook\TypeAssert; | ||
use PHPUnit\Framework\TestCase; | ||
use Nazg\Foundation\Validation\Validator; | ||
use Zend\Diactoros\ServerRequestFactory; | ||
|
||
class ValidatorTest extends TestCase { | ||
|
||
public function testShouldBeValidatorFailed(): void { | ||
$v = new MockValidateFalied(); | ||
$this->assertNotCount(0, $v->errors()); | ||
$this->assertFalse($v->validate()); | ||
} | ||
|
||
/** | ||
* @expectedException \Facebook\TypeAssert\IncorrectTypeException | ||
*/ | ||
public function testShouldThrowTypeException(): void { | ||
$v = new MockStructureValidateFalied(); | ||
$request = ServerRequestFactory::fromGlobals([ | ||
'REQUEST_URI' => '/testing/12?message=testing&server=hhvm', | ||
'QUERY_STRING' => 'message=testing&server=hhvm', | ||
'REQUEST_METHOD' => 'GET' | ||
], | ||
[ | ||
'message' => 'testing', | ||
'server' => 'hhvm', | ||
]); | ||
$v->validateRequest($request); | ||
$v->validate(); | ||
} | ||
|
||
public function testShouldThrow(): void { | ||
$v = new MockStructureValidateSuccess(); | ||
$request = ServerRequestFactory::fromGlobals([ | ||
'REQUEST_URI' => '/testing/12?message=testing&server=hhvm', | ||
'QUERY_STRING' => 'message=testing&server=hhvm', | ||
'REQUEST_METHOD' => 'GET' | ||
], | ||
[ | ||
'message' => 'testing', | ||
'server' => 'hhvm', | ||
]); | ||
$v->validateRequest($request); | ||
$this->assertTrue($v->validate()); | ||
} | ||
} | ||
|
||
class MockValidateFalied extends Validator { | ||
|
||
protected bool $shouldThrowException = false; | ||
|
||
protected function assertValidateResult(): Vector<string> { | ||
return new Vector(['error1']); | ||
} | ||
} | ||
|
||
class MockStructureValidateFalied extends Validator { | ||
|
||
const type TestRequest = shape( | ||
'message' => string, | ||
'server' => int, | ||
); | ||
|
||
protected bool $shouldThrowException = false; | ||
protected bool $skipValidateStructure = false; | ||
protected function assertValidateResult(): Vector<string> { | ||
return new Vector(['error1']); | ||
} | ||
|
||
protected function assertStructure(): void { | ||
if(!$this->skipValidateStructure) { | ||
TypeAssert\matches_type_structure( | ||
type_structure(self::class, 'TestRequest'), | ||
$this->request->getQueryParams(), | ||
); | ||
} | ||
} | ||
} | ||
|
||
class MockStructureValidateSuccess extends Validator { | ||
|
||
const type TestRequest = shape( | ||
'message' => string, | ||
'server' => string, | ||
); | ||
|
||
protected bool $shouldThrowException = false; | ||
protected bool $skipValidateStructure = false; | ||
protected function assertValidateResult(): Vector<string> { | ||
$params = $this->request->getQueryParams(); | ||
$v = Vector{}; | ||
if ($params['message'] !== 'testing') { | ||
$v = $v->concat(['error!']); | ||
} | ||
return $v; | ||
} | ||
|
||
protected function assertStructure(): void { | ||
if(!$this->skipValidateStructure) { | ||
TypeAssert\matches_type_structure( | ||
type_structure(self::class, 'TestRequest'), | ||
$this->request->getQueryParams(), | ||
); | ||
} | ||
} | ||
} |